Skip to content

Commit c25478b

Browse files
Further testing
1 parent 08d7ef3 commit c25478b

File tree

8 files changed

+150
-22
lines changed

8 files changed

+150
-22
lines changed

docs/SimpleEmployerExample.png

12.7 KB
Loading

docs/uml2semantics.qea

0 Bytes
Binary file not shown.

src/main/scala/org/uml2semantics/model/UMLClassDiagram.scala

Lines changed: 17 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -554,12 +554,9 @@ case class UMLClass(classIdentity: UMLClassIdentity,
554554
case class UMLClassAttributeDefinition(definition: String = "")
555555

556556
sealed trait UMLClassAttributeType
557-
558557
case class UMLXMLDataType(attributeType: SupportedDataType) extends UMLClassAttributeType
559-
560558
case class UMLClassIdentityType(attributeType: UMLClassIdentity) extends UMLClassAttributeType
561-
562-
559+
case class UMLEnumerationIdentityType(attributeType: UMLEnumerationIdentity) extends UMLClassAttributeType
563560
case class CurieBasedUMLClassAttributeType(attributeType: Curie) extends UMLClassAttributeType
564561

565562
//case class UndefinedUMLClassAttributeType() extends UMLClassAttributeType
@@ -571,20 +568,25 @@ object UMLClassAttributeType:
571568

572569
def apply(s: String): UMLClassAttributeType =
573570
logger.debug(s"s=$s ${Code.source}")
574-
require(UMLClassIdentity.findClassNamedElement(s).nonEmpty || SupportedDataType.unapply(s).nonEmpty
575-
|| Curie.isCurieBasedOnConfiguredPrefix(s) || s.isEmpty,
576-
s"""A class attribute must have a type that is either a class, that has been specified,
571+
require(UMLClassIdentity.findClassNamedElement(s).nonEmpty ||
572+
UMLEnumerationIdentity.findEnumerationNamedElement(s).nonEmpty ||
573+
SupportedDataType.unapply(s).nonEmpty ||
574+
Curie.isCurieBasedOnConfiguredPrefix(s) ||
575+
s.isEmpty,
576+
s"""A class attribute must have a type that is either a class or enumeration, that has been specified,
577577
or an XML data type or an curie based on a known prefix. Prefixes are specified using the -x option when running uml2semantics.
578-
"$s" is not recognised as either a class or an XML data type.""")
578+
"$s" is not recognised as either a class or an enumeration or an XML data type.""")
579579
UMLClassIdentity.findClassNamedElement(s) match
580580
case Some(classNamedElement) => UMLClassIdentityType(classNamedElement)
581-
case None => SupportedDataType.unapply(s) match
582-
case Some(x) => UMLXMLDataType(x)
583-
case None =>
584-
val curieOption: Option[Curie] = Curie.unapply(s)
585-
curieOption match
586-
case Some(curie) => CurieBasedUMLClassAttributeType(curie)
587-
case None => UndefinedUMLClassAttributeType
581+
case None => UMLEnumerationIdentity.findEnumerationNamedElement(s) match
582+
case Some(enumerationNamedElement) => UMLEnumerationIdentityType(enumerationNamedElement)
583+
case None => SupportedDataType.unapply(s) match
584+
case Some(x) => UMLXMLDataType(x)
585+
case None =>
586+
val curieOption: Option[Curie] = Curie.unapply(s)
587+
curieOption match
588+
case Some(curie) => CurieBasedUMLClassAttributeType(curie)
589+
case None => UndefinedUMLClassAttributeType
588590

589591
def unapply(s: String): Option[UMLClassAttributeType] =
590592
logger.debug(s"s=$s ${Code.source}")

src/main/scala/org/uml2semantics/owl/UML2OWLWriter.scala

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,8 @@ class UML2OWLWriter(val umlClassDiagram: UMLClassDiagram):
8787
owlProperty = createOWLDataProperty(umlClassAttribute, errorMessages, domain, attributeType)
8888
case UMLClassIdentityType(attributeType) =>
8989
owlProperty = createOWLObjectProperty(umlClassAttribute, errorMessages, domain, attributeType)
90+
case UMLEnumerationIdentityType(attributeType) =>
91+
owlProperty = createOWLObjectProperty(umlClassAttribute, errorMessages, domain, attributeType)
9092
case CurieBasedUMLClassAttributeType(attributeType) =>
9193
owlProperty = createOWLObjectPropertyBasedOnConfiguredPrefix(umlClassAttribute, errorMessages, domain, attributeType)
9294
case UndefinedUMLClassAttributeType =>
@@ -157,6 +159,56 @@ class UML2OWLWriter(val umlClassDiagram: UMLClassDiagram):
157159
case UMLMultiplicity(UMLInfiniteCardinality(_), UMLInfiniteCardinality(_)) =>
158160
objectProperty
159161

162+
private def createOWLObjectProperty(umlClassAttribute: UMLClassAttribute,
163+
errorMessages: mutable.Seq[String],
164+
domain: OWLClass,
165+
umlEnumerationIdentity: UMLEnumerationIdentity): OWLObjectProperty =
166+
logger.debug(s"createOWLObjectProperty: umlClassAttribute=$umlClassAttribute, errorMessages = $errorMessages, " +
167+
s"domain=$domain, umlEnumerationIdentity=$umlEnumerationIdentity ${Code.source}")
168+
val objectProperty = dataFactory.getOWLObjectProperty(umlClassAttribute.attributeIdentity.attributeIRI.iri)
169+
val domainChangeApplied = manager.addAxiom(ontology, dataFactory.getOWLObjectPropertyDomainAxiom(objectProperty, domain))
170+
if domainChangeApplied != SUCCESSFULLY then
171+
errorMessages :+ s"Domain axiom for object property ${objectProperty.getIRI} could not be added for " +
172+
s"${umlClassAttribute.attributeIdentity.attributeIRI.iri}"
173+
val rangeChangeApplied = manager.addAxiom(ontology, dataFactory.getOWLObjectPropertyRangeAxiom(objectProperty,
174+
dataFactory.getOWLClass(umlEnumerationIdentity.enumerationIRI.iri)))
175+
if rangeChangeApplied != SUCCESSFULLY then
176+
errorMessages :+ s"Range axiom for data property ${objectProperty.getIRI} could not be added for " +
177+
s"${umlClassAttribute.attributeIdentity.attributeIRI.iri}"
178+
umlClassAttribute.multiplicity match
179+
case UMLMultiplicity(UMLNonNegativeCardinality(minCardinality), UMLNonNegativeCardinality(maxCardinality)) =>
180+
logger.trace(s"minCardinality=$minCardinality ${Code.source}")
181+
val axiom =
182+
if minCardinality == maxCardinality && minCardinality != 0 then
183+
dataFactory.getOWLSubClassOfAxiom(domain, dataFactory.getOWLObjectExactCardinality(maxCardinality, objectProperty,
184+
dataFactory.getOWLClass(umlEnumerationIdentity.enumerationIRI.iri)))
185+
else if minCardinality > 0 then
186+
dataFactory.getOWLSubClassOfAxiom(domain,
187+
dataFactory.getOWLObjectIntersectionOf(
188+
dataFactory.getOWLObjectMinCardinality(minCardinality, objectProperty,
189+
dataFactory.getOWLClass(umlEnumerationIdentity.enumerationIRI.iri)),
190+
dataFactory.getOWLObjectMaxCardinality(maxCardinality, objectProperty,
191+
dataFactory.getOWLClass(umlEnumerationIdentity.enumerationIRI.iri))))
192+
else
193+
dataFactory.getOWLSubClassOfAxiom(domain, dataFactory.getOWLObjectMaxCardinality(maxCardinality, objectProperty,
194+
dataFactory.getOWLClass(umlEnumerationIdentity.enumerationIRI.iri)))
195+
if manager.addAxiom(ontology, axiom) != SUCCESSFULLY then
196+
errorMessages :+ s"Could not add subclass axiom representing cardinalities [$minCardinality, $maxCardinality] for " +
197+
s"${umlClassAttribute.attributeIdentity.attributeLabel}"
198+
case UMLMultiplicity(UMLNonNegativeCardinality(minCardinality), UMLInfiniteCardinality(_)) =>
199+
if minCardinality > 0 then
200+
val axiom = dataFactory.getOWLSubClassOfAxiom(domain,
201+
dataFactory.getOWLObjectMinCardinality(minCardinality, objectProperty,
202+
dataFactory.getOWLClass(umlEnumerationIdentity.enumerationIRI.iri)))
203+
if manager.addAxiom(ontology, axiom) != SUCCESSFULLY then
204+
errorMessages :+ s"Could not add subclass axiom representing cardinalities for [$minCardinality, *]" +
205+
s"${umlClassAttribute.attributeIdentity.attributeLabel}"
206+
case UMLMultiplicity(UMLInfiniteCardinality(_), UMLNonNegativeCardinality(maxCardinality)) =>
207+
errorMessages :+ s"Multiplicity error found with multiplicity = [*, $maxCardinality] for attribute = " +
208+
s"${umlClassAttribute.attributeIdentity.attributeLabel}."
209+
case UMLMultiplicity(UMLInfiniteCardinality(_), UMLInfiniteCardinality(_)) =>
210+
objectProperty
211+
160212
private def createOWLObjectProperty(umlClassAttribute: UMLClassAttribute,
161213
errorMessages: mutable.Seq[String],
162214
domain: OWLClass): OWLObjectProperty =

src/main/scala/org/uml2semantics/reader/TSVReader.scala

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -79,8 +79,9 @@ def parseAttributes(maybeTsvFile: Option[File], ontologyPrefix: PrefixNamespace)
7979
logger.trace(s"m = $m")
8080

8181
val classNamedElement = UMLClassIdentity.findClassNamedElement(m(ClassAttributesHeader.ClassName.toString))
82+
val enumerationNamedElement = UMLEnumerationIdentity.findEnumerationNamedElement(m(ClassAttributesHeader.ClassName.toString))
8283
logger.trace(s"classNamedElement = $classNamedElement")
83-
if classNamedElement.isDefined then
84+
if classNamedElement.isDefined || enumerationNamedElement.isDefined then
8485
logger.trace(s"mClassOrPrimitiveType.toString = {${m(ClassOrPrimitiveType.toString)}}")
8586
val curieOption: Option[Curie] = if m(Curie.toString).contains(":") then
8687
Some(org.uml2semantics.model.Curie(m(Curie.toString)))
@@ -191,14 +192,19 @@ def parseEnumerationValues(maybeTsvFile: Option[File], ontologyPrefix: PrefixNam
191192
end parseEnumerationValues
192193

193194
def parseUMLClassDiagram(input: InputParameters): UMLClassDiagram =
195+
var umlClasses = parseClasses(input.classesTsv, PrefixNamespace(input.ontologyPrefix))
196+
var umlEnumerations = parseEnumerations(input.enumerationsTsv, PrefixNamespace(input.ontologyPrefix))
197+
var umlAttributes = parseAttributes(input.attributesTsv, PrefixNamespace(input.ontologyPrefix))
198+
var umlEnumerationValues = parseEnumerationValues(input.enumerationValuesTsv, PrefixNamespace(input.ontologyPrefix))
199+
194200
UMLClassDiagram(
195201
input.owlOntologyFile.get,
196202
OntologyIRI(input.ontologyIRI),
197203
PrefixNamespace(input.ontologyPrefix),
198-
parseClasses(input.classesTsv, PrefixNamespace(input.ontologyPrefix)),
199-
parseAttributes(input.attributesTsv, PrefixNamespace(input.ontologyPrefix)),
200-
parseEnumerations(input.enumerationsTsv, PrefixNamespace(input.ontologyPrefix)),
201-
parseEnumerationValues(input.enumerationValuesTsv, PrefixNamespace(input.ontologyPrefix)))
204+
umlClasses,
205+
umlAttributes,
206+
umlEnumerations,
207+
umlEnumerationValues)
202208

203209

204210

src/test/resources/Employer - Attributes.tsv

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,4 +3,7 @@ Person name xsd:string
33
Person surname xsd:string
44
Person dateOfBirth xsd:dateTime
55
Employee employedBy Employer 1 1
6-
Employer employes Employee 1 *
6+
Employee renumeration Renumeration 1 1
7+
Employer employes Employee 1 *
8+
Renumeration rate xsd:decimal 1 1
9+
Renumeration paymentSchedule PaymentSchedule 1 1
Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
Curie Name Definition ParentNames
22
Person
33
Employee Person
4-
Employer Person
4+
Employer Person
5+
Renumeration

src/test/resources/employer.rdf

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,17 @@
3333

3434

3535

36+
<!-- http://uml2semantics.org/examples/employer#Employee/renumeration -->
37+
38+
39+
<owl:ObjectProperty rdf:about="http://uml2semantics.org/examples/employer#Employee/renumeration">
40+
<rdfs:domain rdf:resource="http://uml2semantics.org/examples/employer#Employee"/>
41+
<rdfs:range rdf:resource="http://uml2semantics.org/examples/employer#Renumeration"/>
42+
<rdfs:label>renumeration</rdfs:label>
43+
</owl:ObjectProperty>
44+
45+
46+
3647
<!-- http://uml2semantics.org/examples/employer#Employer/employes -->
3748

3849

@@ -44,6 +55,17 @@
4455

4556

4657

58+
<!-- http://uml2semantics.org/examples/employer#Renumeration/paymentSchedule -->
59+
60+
61+
<owl:ObjectProperty rdf:about="http://uml2semantics.org/examples/employer#Renumeration/paymentSchedule">
62+
<rdfs:domain rdf:resource="http://uml2semantics.org/examples/employer#Renumeration"/>
63+
<rdfs:range rdf:resource="http://uml2semantics.org/examples/employer#SalarySchedule"/>
64+
<rdfs:label>paymentSchedule</rdfs:label>
65+
</owl:ObjectProperty>
66+
67+
68+
4769
<!--
4870
///////////////////////////////////////////////////////////////////////////////////////
4971
//
@@ -89,6 +111,17 @@
89111

90112

91113

114+
<!-- http://uml2semantics.org/examples/employer#Renumeration/rate -->
115+
116+
117+
<owl:DatatypeProperty rdf:about="http://uml2semantics.org/examples/employer#Renumeration/rate">
118+
<rdfs:domain rdf:resource="http://uml2semantics.org/examples/employer#Renumeration"/>
119+
<rdfs:range rdf:resource="http://www.w3.org/2001/XMLSchema#decimal"/>
120+
<rdfs:label>rate</rdfs:label>
121+
</owl:DatatypeProperty>
122+
123+
124+
92125
<!--
93126
///////////////////////////////////////////////////////////////////////////////////////
94127
//
@@ -113,6 +146,13 @@
113146
<owl:onClass rdf:resource="http://uml2semantics.org/examples/employer#Employer"/>
114147
</owl:Restriction>
115148
</rdfs:subClassOf>
149+
<rdfs:subClassOf>
150+
<owl:Restriction>
151+
<owl:onProperty rdf:resource="http://uml2semantics.org/examples/employer#Employee/renumeration"/>
152+
<owl:qualifiedCardinality rdf:datatype="http://www.w3.org/2001/XMLSchema#nonNegativeInteger">1</owl:qualifiedCardinality>
153+
<owl:onClass rdf:resource="http://uml2semantics.org/examples/employer#Renumeration"/>
154+
</owl:Restriction>
155+
</rdfs:subClassOf>
116156
<rdfs:label>Employee</rdfs:label>
117157
</owl:Class>
118158

@@ -166,6 +206,30 @@
166206

167207

168208

209+
<!-- http://uml2semantics.org/examples/employer#Renumeration -->
210+
211+
212+
<owl:Class rdf:about="http://uml2semantics.org/examples/employer#Renumeration">
213+
<rdfs:subClassOf rdf:resource="http://www.w3.org/2002/07/owl#Thing"/>
214+
<rdfs:subClassOf>
215+
<owl:Restriction>
216+
<owl:onProperty rdf:resource="http://uml2semantics.org/examples/employer#Renumeration/paymentSchedule"/>
217+
<owl:qualifiedCardinality rdf:datatype="http://www.w3.org/2001/XMLSchema#nonNegativeInteger">1</owl:qualifiedCardinality>
218+
<owl:onClass rdf:resource="http://uml2semantics.org/examples/employer#SalarySchedule"/>
219+
</owl:Restriction>
220+
</rdfs:subClassOf>
221+
<rdfs:subClassOf>
222+
<owl:Restriction>
223+
<owl:onProperty rdf:resource="http://uml2semantics.org/examples/employer#Renumeration/rate"/>
224+
<owl:qualifiedCardinality rdf:datatype="http://www.w3.org/2001/XMLSchema#nonNegativeInteger">1</owl:qualifiedCardinality>
225+
<owl:onDataRange rdf:resource="http://www.w3.org/2001/XMLSchema#decimal"/>
226+
</owl:Restriction>
227+
</rdfs:subClassOf>
228+
<rdfs:label>Renumeration</rdfs:label>
229+
</owl:Class>
230+
231+
232+
169233
<!-- http://uml2semantics.org/examples/employer#SalarySchedule -->
170234

171235

0 commit comments

Comments
 (0)