diff --git a/examples/omwg/total-owlable.xml b/examples/omwg/total-owlable.xml new file mode 100644 index 0000000000000000000000000000000000000000..03b5d116e6a59157cd0f05432bde4fbfdba4cbef --- /dev/null +++ b/examples/omwg/total-owlable.xml @@ -0,0 +1,463 @@ +<?xml version="1.0" encoding="utf-8" standalone="no"?> +<!DOCTYPE rdf:RDF [ +<!ENTITY xsd "http://www.w3.org/2001/XMLSchema#"> +<!ENTITY wine "http://www.w3.org/TR/2003/CR-owl-guide-20030818/wine#"> +<!ENTITY vin "http://ontology.deri.org/vin#"> +<!ENTITY proton "http://proton.semanticweb.org/"> +]> + +<!-- JE2010: With the "#" in the end, this is parsed (by the RDF parser...) + without it, this is not! --> +<rdf:RDF xmlns="http://knowledgeweb.semanticweb.org/heterogeneity/alignment#" + xml:base="http://oms.omwg.org/wine-vin/" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:xsd="http://www.w3.org/2001/XMLSchema#" + xmlns:align="http://knowledgeweb.semanticweb.org/heterogeneity/alignment#" + xmlns:rdfs="http://www.w3.org/2000/01/rdf-schema#" + xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:ex="http://example.org" + xmlns:wine="http://www.w3.org/TR/2003/CR-owl-guide-20030818/wine#" + xmlns:vin="http://ontology.deri.org/vin#" + xmlns:proton="http://proton.semanticweb.org/" + xmlns:edoal="http://ns.inria.org/edoal/1.0/#"> + + <Alignment rdf:about="http://oms.omwg.org/wine-vin/"> + <xml>yes</xml> + <dc:creator>http://www.scharffe.fr/foaf.rdf</dc:creator> + <dc:date>2010/10/10</dc:date> + <method>manual</method> + <purpose>example</purpose> + <rdf:comment>This is a transformation of total.xml which can be transformed in OWL</rdf:comment> + <level>2EDOAL</level> + <type>**</type> + <onto1> + <Ontology rdf:about="&wine;"> + <formalism> + <Formalism> + <uri>http://www.w3.org/TR/owl-guide/</uri> + <name>owl</name> + </Formalism> + </formalism> + </Ontology> + </onto1> + <onto2> + <Ontology rdf:about="&vin;"> + <location>http://www.scharffe.fr/ontologies/OntologieDuVin.wsml</location> + <formalism> + <Formalism align:uri="http://www.wsmo.org/wsml/wsml-syntax/wsml-dl" + align:name="wsml" /> + </formalism> + </Ontology> + </onto2> + + <!-- Class basis --> + <map> + <Cell rdf:about="MappingRule_class_basis"> + <entity1><edoal:Class rdf:about="&wine;VintageYear"/></entity1> + <entity2><edoal:Class rdf:about="&vin;Millesime"/></entity2> + <measure rdf:datatype="&xsd;float">1.0</measure> + <relation>Equivalence</relation> + </Cell> + </map> + <!-- class const: and or not --> + <map> + <Cell rdf:about="MappingRule_class_const"> + <entity1> + <edoal:Class> + <edoal:not> + <edoal:Class> + <edoal:and rdf:parseType="Collection"> + <edoal:Class> + <edoal:or rdf:parseType="Collection"> + <edoal:Class> + <edoal:and rdf:parseType="Collection"> + <edoal:Class rdf:about="&wine;Bordeaux1"/> + <edoal:Class rdf:about="&wine;Bordeaux2"/> + </edoal:and> + </edoal:Class> + <edoal:Class> + <edoal:not> + <edoal:Class rdf:about="&wine;Bordeaux3"/> + </edoal:not> + </edoal:Class> + </edoal:or> + </edoal:Class> + <edoal:Class> + <edoal:not> + <edoal:Class rdf:about="&wine;Bordeaux4"/> + </edoal:not> + </edoal:Class> + </edoal:and> + </edoal:Class> + </edoal:not> + </edoal:Class> + </entity1> + <entity2> + <edoal:Class> + <edoal:and rdf:parseType="Collection"> + <edoal:Class rdf:about="&vin;Vin"/> + <edoal:Class> + <edoal:or rdf:parseType="Collection"> + <edoal:Class> + <edoal:not> + <edoal:Class rdf:about="&vin;Bordeaux5"/> + </edoal:not> + </edoal:Class> + <edoal:Class rdf:about="&vin;Bordeaux6"/> + </edoal:or> + </edoal:Class> + <edoal:Class> + <edoal:and rdf:parseType="Collection"> + <edoal:Class> + <edoal:not> + <edoal:Class rdf:about="&vin;Bordeaux7"/> + </edoal:not> + </edoal:Class> + <edoal:Class rdf:about="&vin;Bordeaux7"/> + </edoal:and> + </edoal:Class> + </edoal:and> + </edoal:Class> + </entity2> + <measure rdf:datatype='&xsd;float'>1.</measure> + <relation>SubsumedBy</relation> + </Cell> + </map> + <!-- class rest: att-type... --> + <map> + <Cell rdf:about="MappingRule_class_rest"> + <entity1> + <edoal:Class> + <edoal:or rdf:parseType="Collection"> + <edoal:Class rdf:about="&wine;Vin"/> + <edoal:AttributeDomainRestriction> + <edoal:onAttribute> + <edoal:Relation rdf:about="&proton;locatedIn"/> + </edoal:onAttribute> + <edoal:class><edoal:Class rdf:about="&wine;FrenchRegion"/></edoal:class> + </edoal:AttributeDomainRestriction> + <edoal:AttributeTypeRestriction> + <edoal:onAttribute> + <edoal:Relation rdf:about="&wine;hasTerroir"/> + </edoal:onAttribute> + <edoal:datatype>An-integer-as-datatype</edoal:datatype> + </edoal:AttributeTypeRestriction> + <edoal:AttributeOccurenceRestriction> + <edoal:onAttribute> + <edoal:Relation rdf:about="&wine;hasTerroir"/> + </edoal:onAttribute> + <edoal:comparator rdf:resource="&xsd;lower-than"/> + <edoal:value>12</edoal:value> + </edoal:AttributeOccurenceRestriction> + <edoal:Class rdf:about="&wine;Bordeaux7"/> + </edoal:or> + </edoal:Class> + </entity1> + <entity2> + <edoal:Class> + <edoal:and rdf:parseType="Collection"> + <edoal:Class rdf:about="&vin;Vin"/> + <edoal:AttributeValueRestriction> + <edoal:onAttribute> + <edoal:Relation rdf:about="&vin;hasTerroir"/> + </edoal:onAttribute> + <edoal:comparator rdf:resource="&xsd;equals"/> + <edoal:value><edoal:Instance rdf:about="&vin;Aquitaine"/></edoal:value> + </edoal:AttributeValueRestriction> + <edoal:AttributeOccurenceRestriction> + <edoal:onAttribute> + <edoal:Relation rdf:about="&proton;locatedIn"/> + </edoal:onAttribute> + <edoal:comparator rdf:resource="&xsd;greater-than"/> + <edoal:value>4</edoal:value> + </edoal:AttributeOccurenceRestriction> + </edoal:and> + </edoal:Class> + </entity2> + <measure rdf:datatype='&xsd;float'>1.</measure> + <relation>SubsumedBy</relation> + </Cell> + </map> + <!-- test the quantifiers --> + <map> + <Cell rdf:about="MappingRule_class_quant"> + <entity1> + <edoal:Class> + <edoal:or rdf:parseType="Collection"> + <edoal:Class rdf:about="&wine;Vin"/> + <edoal:AttributeDomainRestriction> + <edoal:onAttribute> + <edoal:Relation rdf:about="&wine;hasTerroir"/> + </edoal:onAttribute> + <edoal:all><edoal:Class rdf:about="&wine;FrenchRegion"/></edoal:all> + </edoal:AttributeDomainRestriction> + </edoal:or> + </edoal:Class> + </entity1> + <entity2> + <edoal:Class> + <edoal:and rdf:parseType="Collection"> + <edoal:Class rdf:about="&vin;Vin"/> + <edoal:AttributeDomainRestriction> + <edoal:onAttribute> + <edoal:Relation rdf:about="&vin;hasTerroir"/> + </edoal:onAttribute> + <edoal:exists><edoal:Class rdf:about="&wine;FrenchRegion"/></edoal:exists> + </edoal:AttributeDomainRestriction> + </edoal:and> + </edoal:Class> + </entity2> + <measure rdf:datatype='&xsd;float'>1.</measure> + <relation>SubsumedBy</relation> + </Cell> + </map> + <!-- a bit more test on values --> + <map> + <Cell rdf:about="MappingRule_class_values"> + <entity1> + <edoal:Class> + <edoal:or rdf:parseType="Collection"> + <edoal:Class rdf:about="&wine;Vin"/> + <edoal:AttributeValueRestriction> + <edoal:onAttribute> + <edoal:Relation rdf:about="&wine;hasTerroir"/> + </edoal:onAttribute> + <edoal:comparator rdf:resource="&xsd;equals"/> + <edoal:value><edoal:Instance rdf:about="&wine;Bordelais"/></edoal:value> + </edoal:AttributeValueRestriction> + <edoal:Class rdf:about="&wine;Bordeaux7"/> + </edoal:or> + </edoal:Class> + </entity1> + <entity2> + <edoal:Class> + <edoal:and rdf:parseType="Collection"> + <edoal:Class rdf:about="&vin;Vin"/> + <edoal:AttributeValueRestriction> + <edoal:onAttribute> + <edoal:Relation rdf:about="&wine;hasTerroir"/> + </edoal:onAttribute> + <edoal:comparator rdf:resource="&xsd;equals"/> + <edoal:value><edoal:Literal edoal:string="33"/></edoal:value> + </edoal:AttributeValueRestriction> + </edoal:and> + </edoal:Class> + </entity2> + <measure rdf:datatype='&xsd;float'>1.</measure> + <relation>SubsumedBy</relation> + </Cell> + </map> + <!-- class const and rest --> + <!-- rel basis --> + <map> + <Cell rdf:about="MappingRule_rel_basis"> + <entity1><edoal:Relation rdf:about="&wine;locatedIn"/></entity1> + <entity2><edoal:Relation rdf:about="&vin;hasTerroir"/></entity2> + <measure rdf:datatype="&xsd;float">1.0</measure> + <relation>SubsumedBy</relation> + </Cell> + </map> + <!-- rel const: and or not compose inverse trans refl sym --> + <map> + <Cell rdf:about="MappingRule_rel_const"> + <entity1> + <edoal:Relation> + <edoal:inverse> + <edoal:Relation rdf:about="&wine;loc4"/> + </edoal:inverse> + </edoal:Relation> + </entity1> + <entity2> + <edoal:Relation rdf:about="&vin;place3"/> + </entity2> + <measure rdf:datatype='&xsd;float'>1.</measure> + <relation>SubsumedBy</relation> + </Cell> + </map> + <!-- rel rest: att-type... --> + <map> + <Cell rdf:about="MappingRule_rel_rest"> + <entity1> + <edoal:RelationDomainRestriction> + <edoal:class><edoal:Class rdf:about="&wine;Bordeaux1"/></edoal:class> + </edoal:RelationDomainRestriction> + </entity1> + <entity2> + <edoal:RelationDomainRestriction> + <edoal:class> + <edoal:Class> + <edoal:and rdf:parseType="Collection"> + <edoal:Class rdf:about="&vin;Bordeaux5"/> + <edoal:Class rdf:about="&vin;Bordeaux6"/> + </edoal:and> + </edoal:Class> + </edoal:class> + </edoal:RelationDomainRestriction> + </entity2> + <measure rdf:datatype='&xsd;float'>1.</measure> + <relation>SubsumedBy</relation> + </Cell> + </map> + <!-- rel const and rest --> + <!-- prop basis --> + <map> + <Cell rdf:about="MappingRule_prop_basis"> + <entity1><edoal:Property rdf:about="&wine;yearValue"/></entity1> + <entity2><edoal:Property rdf:about="&vin;anneeMillesime"/></entity2> + <measure rdf:datatype="&xsd;float">1.0</measure> + <relation>Equivalence</relation> + </Cell> + </map> + <!-- prop const: and or not compose --> + <map> + <Cell rdf:about="MappingRule_prop_const"> + <entity1> + <edoal:Property rdf:about="&wine;number1"/> + </entity1> + <entity2> + <edoal:Property rdf:about="&vin;dpt3"/> + </entity2> + <measure rdf:datatype='&xsd;float'>1.</measure> + <relation>SubsumedBy</relation> + </Cell> + </map> + <!-- prop rest: att-type... --> + <map> + <Cell rdf:about="MappingRule_prop_rest"> + <entity1> + <edoal:PropertyValueRestriction> + <edoal:comparator rdf:resource="http://www.w3.org/2001/XMLSchema#equals"/> + <edoal:value><edoal:Literal edoal:string="Bordeaux"/></edoal:value> + </edoal:PropertyValueRestriction> + </entity1> + <entity2> + <edoal:PropertyDomainRestriction> + <edoal:class> + <edoal:Class> + <edoal:and rdf:parseType="Collection"> + <edoal:Class rdf:about="&vin;Bordeaux5"/> + <edoal:Class rdf:about="&vin;Bordeaux6"/> + </edoal:and> + </edoal:Class> + </edoal:class> + </edoal:PropertyDomainRestriction> + </entity2> + <measure rdf:datatype='&xsd;float'>1.</measure> + <relation>SubsumedBy</relation> + </Cell> + </map> + <!-- prop const and rest --> + <!-- instance --> + <map> + <Cell rdf:about="MappingRule_inst_basis"> + <entity1><edoal:Instance rdf:about="&wine;ChateauMargaux1995"/></entity1> + <entity2><edoal:Instance rdf:about="&vin;MoutonRotschild1889"/></entity2> + <measure rdf:datatype="&xsd;float">1.0</measure> + <relation>Equivalence</relation> + </Cell> + </map> + <!-- Miscelaneous --> + <map> + <Cell rdf:about="MappingRule_3"> + <entity1> + <edoal:Class> + <edoal:and rdf:parseType="Collection"> + <edoal:Class rdf:about="&wine;Bordeaux17"/> + <edoal:Class> + <edoal:or rdf:parseType="Collection"> + <edoal:Class rdf:about="&wine;Bordeaux18"/> + <edoal:Class rdf:about="&wine;Bordeaux18"/> + </edoal:or> + </edoal:Class> + </edoal:and> + </edoal:Class> + </entity1> + <entity2> + <edoal:Class rdf:about="&vin;Vin"/> + </entity2> + <measure rdf:datatype='&xsd;float'>1.</measure> + <relation>SubsumedBy</relation> + </Cell> + </map> + <map> + <Cell rdf:about="MappingRule_4"> + <entity1> + <edoal:Class> + <edoal:or rdf:parseType="Collection"> + <edoal:Class rdf:about="&vin;Acidite"/> + <edoal:Class rdf:about="&vin;Astreingence"/> + <edoal:Class rdf:about="&vin;Amertume"/> + </edoal:or> + </edoal:Class> + </entity1> + <entity2> + <edoal:Class> + <edoal:not> + <edoal:Class rdf:about="&vin;WineFlavor"/> + </edoal:not> + </edoal:Class> + </entity2> + <measure rdf:datatype='&xsd;float'>1.</measure> + <relation>SubsumedBy</relation> + </Cell> + </map> + <!-- The transformation will be ignored by OWL --> + <map> + <Cell rdf:about="TransformationTest"> + <entity1> + <edoal:Property rdf:about="foaf:name"/> + </entity1> + <entity2> + <edoal:Relation rdf:about="vcard:name"/> + </entity2> + <measure rdf:datatype='&xsd;float'>1.</measure> + <relation>SubsumedBy</relation> + <edoal:transformation> + <edoal:Transformation edoal:type="o-"> + <edoal:entity1> + <edoal:Property><edoal:compose rdf:parseType="Collection"/></edoal:Property> + </edoal:entity1> + <edoal:entity2> + <edoal:Apply edoal:operator="concat"> + <edoal:arguments rdf:parseType="Collection"> + <edoal:Property rdf:about="vcard:firstname"/> + <edoal:Literal edoal:string=" "/> + <!-- or even compute middle initial from middlename --> + <edoal:Property rdf:about="vcard:middleinitial"/> + <edoal:Literal edoal:string=". "/> + <edoal:Property rdf:about="vcard:lastname"/> + </edoal:arguments> + </edoal:Apply> + </edoal:entity2> + </edoal:Transformation> + </edoal:transformation> + </Cell> + </map> +<!-- TOCHECK DOES NOT WORK BECAUSE OF OUT TOP/BOTTOM --> + <map> + <Cell rdf:about="ExtremeTransformationTest"> + <entity1> + <edoal:Class> + <edoal:or /> + </edoal:Class> + </entity1> + <entity2> + <edoal:Class> + <edoal:and /> + </edoal:Class> + </entity2> + <measure rdf:datatype='&xsd;float'>1.</measure> + <relation>SubsumedBy</relation> + <edoal:transformation> + <edoal:Transformation edoal:type="o-"> + <edoal:entity1> + <edoal:Relation><edoal:compose /></edoal:Relation> + </edoal:entity1> + <edoal:entity2> + <edoal:Relation><edoal:compose /></edoal:Relation> + </edoal:entity2> + </edoal:Transformation> + </edoal:transformation> + </Cell> + </map> + </Alignment> +</rdf:RDF> diff --git a/examples/omwg/total.xml b/examples/omwg/total.xml index 6f484f370acb06ce6a366cb5fdb3e698460f604e..8f4de9f460847337a6629dd7754d0495a1fa1255 100644 --- a/examples/omwg/total.xml +++ b/examples/omwg/total.xml @@ -158,7 +158,7 @@ </edoal:or> </edoal:Relation> </edoal:onAttribute> - <edoal:comparator rdf:resource="&xsd;less-than"/> + <edoal:comparator rdf:resource="&xsd;lower-than"/> <edoal:value>12</edoal:value> </edoal:AttributeOccurenceRestriction> <edoal:Class rdf:about="&wine;Bordeaux7"/> @@ -234,7 +234,6 @@ </edoal:compose> </edoal:Relation> </edoal:onAttribute> - <edoal:comparator rdf:resource="&xsd;equals"/> <edoal:exists><edoal:Class rdf:about="&wine;FrenchRegion"/></edoal:exists> </edoal:AttributeDomainRestriction> </edoal:and> @@ -627,12 +626,14 @@ </map> <!-- prop const and rest --> <!-- instance --> + <!-- This equivalence does not means anything. + It was a subsumption which was not better --> <map> <Cell rdf:about="MappingRule_inst_basis"> <entity1><edoal:Instance rdf:about="&wine;ChateauMargaux1995"/></entity1> <entity2><edoal:Instance rdf:about="&vin;MoutonRotschild1889"/></entity2> <measure rdf:datatype="&xsd;float">1.0</measure> - <relation>SubsumedBy</relation> + <relation>Equivalence</relation> </Cell> </map> <!-- Miscelaneous --> diff --git a/src/fr/inrialpes/exmo/align/impl/edoal/Comparator.java b/src/fr/inrialpes/exmo/align/impl/edoal/Comparator.java index 745a4062e713ce5964056c60b99a7b55e345c44c..38651cb74b438e2cba24111c9950f95d54ad7d07 100644 --- a/src/fr/inrialpes/exmo/align/impl/edoal/Comparator.java +++ b/src/fr/inrialpes/exmo/align/impl/edoal/Comparator.java @@ -35,6 +35,16 @@ public class Comparator { public static Comparator LOWER = initComparator( Namespace.XSD.prefix+"lower-than", -1 ); public static Comparator GREATER = initComparator( Namespace.XSD.prefix+"greater-than", 1 ); + public static Comparator getComparator( URI u ) { + if ( u.equals( EQUAL.getURI() ) ) { + return EQUAL; + } else if ( u.equals( LOWER.getURI() ) ) { + return LOWER; + } else if ( u.equals( GREATER.getURI() ) ) { + return GREATER; + } else return new Comparator( u ); + } + protected Comparator() { super(); } diff --git a/src/fr/inrialpes/exmo/align/impl/edoal/Datatype.java b/src/fr/inrialpes/exmo/align/impl/edoal/Datatype.java index 0c577757ab63b82a46776f879c6593bac65d9c42..f34ca819238ef54cb99a77cb3dfec444de9c61dd 100644 --- a/src/fr/inrialpes/exmo/align/impl/edoal/Datatype.java +++ b/src/fr/inrialpes/exmo/align/impl/edoal/Datatype.java @@ -22,6 +22,10 @@ package fr.inrialpes.exmo.align.impl.edoal; +import org.semanticweb.owl.align.AlignmentException; +import org.semanticweb.owl.align.AlignmentVisitor; +import org.semanticweb.owl.align.Visitable; + /** * <p> * Id to represent a datatype @@ -31,11 +35,15 @@ package fr.inrialpes.exmo.align.impl.edoal; * </p> */ -public class Datatype { //implements Cloneable, Visitable { +public class Datatype implements Visitable { //implements Cloneable /** Holds the type */ private String type; + public void accept( AlignmentVisitor visitor) throws AlignmentException { + visitor.visit( this ); + } + /** * Constructs an object with the given type. * @@ -53,10 +61,6 @@ public class Datatype { //implements Cloneable, Visitable { this.type = type; } - // public void accept(AlignmentVisitor visitor) throws AlignmentException { - // visitor.visit(this); - // } - public String plainText() { return type; } diff --git a/src/fr/inrialpes/exmo/align/impl/renderer/OWLAxiomsRendererVisitor.java b/src/fr/inrialpes/exmo/align/impl/renderer/OWLAxiomsRendererVisitor.java index 1bfe4006949fb17e1ae76218cd55b2ac104eb570..02042218d51c80b856a36cda8752820723085333 100644 --- a/src/fr/inrialpes/exmo/align/impl/renderer/OWLAxiomsRendererVisitor.java +++ b/src/fr/inrialpes/exmo/align/impl/renderer/OWLAxiomsRendererVisitor.java @@ -34,6 +34,9 @@ import org.semanticweb.owl.align.AlignmentException; import org.semanticweb.owl.align.Cell; import org.semanticweb.owl.align.Relation; +import fr.inrialpes.exmo.align.impl.Annotations; +import fr.inrialpes.exmo.align.impl.Namespace; +import fr.inrialpes.exmo.align.impl.Extensions; import fr.inrialpes.exmo.align.impl.ObjectAlignment; import fr.inrialpes.exmo.align.impl.BasicRelation; import fr.inrialpes.exmo.align.impl.rel.*; @@ -41,6 +44,46 @@ import fr.inrialpes.exmo.align.impl.rel.*; import fr.inrialpes.exmo.ontowrap.LoadedOntology; import fr.inrialpes.exmo.ontowrap.OntowrapException; +import fr.inrialpes.exmo.align.parser.SyntaxElement; +import fr.inrialpes.exmo.align.parser.SyntaxElement.Constructor; + +import fr.inrialpes.exmo.align.impl.edoal.Id; +import fr.inrialpes.exmo.align.impl.edoal.PathExpression; +import fr.inrialpes.exmo.align.impl.edoal.Expression; +import fr.inrialpes.exmo.align.impl.edoal.ClassExpression; +import fr.inrialpes.exmo.align.impl.edoal.ClassId; +import fr.inrialpes.exmo.align.impl.edoal.ClassConstruction; +import fr.inrialpes.exmo.align.impl.edoal.ClassRestriction; +import fr.inrialpes.exmo.align.impl.edoal.ClassTypeRestriction; +import fr.inrialpes.exmo.align.impl.edoal.ClassDomainRestriction; +import fr.inrialpes.exmo.align.impl.edoal.ClassValueRestriction; +import fr.inrialpes.exmo.align.impl.edoal.ClassOccurenceRestriction; +import fr.inrialpes.exmo.align.impl.edoal.PropertyExpression; +import fr.inrialpes.exmo.align.impl.edoal.PropertyId; +import fr.inrialpes.exmo.align.impl.edoal.PropertyConstruction; +import fr.inrialpes.exmo.align.impl.edoal.PropertyRestriction; +import fr.inrialpes.exmo.align.impl.edoal.PropertyDomainRestriction; +import fr.inrialpes.exmo.align.impl.edoal.PropertyTypeRestriction; +import fr.inrialpes.exmo.align.impl.edoal.PropertyValueRestriction; +import fr.inrialpes.exmo.align.impl.edoal.RelationExpression; +import fr.inrialpes.exmo.align.impl.edoal.RelationId; +import fr.inrialpes.exmo.align.impl.edoal.RelationConstruction; +import fr.inrialpes.exmo.align.impl.edoal.RelationRestriction; +import fr.inrialpes.exmo.align.impl.edoal.RelationDomainRestriction; +import fr.inrialpes.exmo.align.impl.edoal.RelationCoDomainRestriction; +import fr.inrialpes.exmo.align.impl.edoal.InstanceExpression; +import fr.inrialpes.exmo.align.impl.edoal.InstanceId; + +import fr.inrialpes.exmo.align.impl.edoal.Transformation; +import fr.inrialpes.exmo.align.impl.edoal.ValueExpression; +import fr.inrialpes.exmo.align.impl.edoal.Value; +import fr.inrialpes.exmo.align.impl.edoal.Apply; +import fr.inrialpes.exmo.align.impl.edoal.Datatype; +import fr.inrialpes.exmo.align.impl.edoal.Comparator; +import fr.inrialpes.exmo.align.impl.edoal.EDOALRelation; +import fr.inrialpes.exmo.align.impl.edoal.EDOALCell; +import fr.inrialpes.exmo.align.impl.edoal.EDOALAlignment; + /** * Renders an alignment as a new ontology merging these. * @@ -48,16 +91,19 @@ import fr.inrialpes.exmo.ontowrap.OntowrapException; * @version $Id$ */ -public class OWLAxiomsRendererVisitor implements AlignmentVisitor { +public class OWLAxiomsRendererVisitor extends IndentedRendererVisitor implements AlignmentVisitor { boolean heterogeneous = false; - PrintWriter writer = null; + boolean edoal = false; Alignment alignment = null; LoadedOntology onto1 = null; LoadedOntology onto2 = null; Cell cell = null; + Relation toProcess = null; + private static Namespace DEF = Namespace.ALIGNMENT; + public OWLAxiomsRendererVisitor( PrintWriter writer ){ - this.writer = writer; + super( writer ); } public void init( Properties p ) { @@ -65,197 +111,840 @@ public class OWLAxiomsRendererVisitor implements AlignmentVisitor { }; public void visit( Visitable o ) throws AlignmentException { - if ( o instanceof Alignment ) visit( (Alignment)o ); + if ( o instanceof Expression ) visit( (Expression)o ); + else if ( o instanceof ValueExpression ) visit( (ValueExpression)o ); + else if ( o instanceof Transformation ) visit( (Transformation)o ); else if ( o instanceof Cell ) visit( (Cell)o ); else if ( o instanceof Relation ) visit( (Relation)o ); + else if ( o instanceof Alignment ) visit( (Alignment)o ); + else throw new AlignmentException( "Cannot dispatch Expression "+o ); } public void visit( Alignment align ) throws AlignmentException { - if ( !( align instanceof ObjectAlignment )) { - throw new AlignmentException("OWLAxiomsRenderer: cannot render simple alignment. Turn them into ObjectAlignment, by toObjectAlignement()"); - } alignment = align; if ( align instanceof ObjectAlignment ){ onto1 = (LoadedOntology)((ObjectAlignment)alignment).getOntologyObject1(); onto2 = (LoadedOntology)((ObjectAlignment)alignment).getOntologyObject2(); + } else if ( align instanceof EDOALAlignment ) { + edoal = true; + } else { + throw new AlignmentException("OWLAxiomsRenderer: cannot render simple alignment. Turn them into ObjectAlignment, by toObjectAlignement() or use EDOALAlignment"); } - writer.print("<rdf:RDF\n"); - writer.print(" xmlns:owl=\"http://www.w3.org/2002/07/owl#\"\n"); - writer.print(" xmlns:rdf=\"http://www.w3.org/1999/02/22-rdf-syntax-ns#\"\n"); - writer.print(" xmlns:rdfs=\"http://www.w3.org/2000/01/rdf-schema#\" \n"); - writer.print(" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema#\">\n\n"); - writer.print(" <owl:Ontology rdf:about=\"\">\n"); - writer.print(" <rdfs:comment>Matched ontologies</rdfs:comment>\n"); - writer.print(" <rdfs:comment>Generated by fr.inrialpes.exmo.align.renderer.OWLAxiomsRendererVisitor</rdfs:comment>\n"); + writer.print("<rdf:RDF"+NL); + writer.print(" xmlns:owl=\"http://www.w3.org/2002/07/owl#\""+NL); + writer.print(" xmlns:rdf=\"http://www.w3.org/1999/02/22-rdf-syntax-ns#\""+NL); + writer.print(" xmlns:rdfs=\"http://www.w3.org/2000/01/rdf-schema#\" "+NL); + writer.print(" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema#\">"+NL+NL); + writer.print(" <owl:Ontology rdf:about=\"\">"+NL); + writer.print(" <rdfs:comment>Matched ontologies</rdfs:comment>"+NL); + writer.print(" <rdfs:comment>Generated by fr.inrialpes.exmo.align.renderer.OWLAxiomsRendererVisitor</rdfs:comment>"+NL); for ( String[] ext : align.getExtensions() ){ - writer.print(" <rdfs:comment>"+ext[1]+": "+ext[2]+"</rdfs:comment>\n"); + writer.print(" <rdfs:comment>"+ext[1]+": "+ext[2]+"</rdfs:comment>"+NL); } - writer.print(" <owl:imports rdf:resource=\""+align.getOntology1URI().toString()+"\"/>\n"); - writer.print(" <owl:imports rdf:resource=\""+align.getOntology2URI().toString()+"\"/>\n"); - writer.print(" </owl:Ontology>\n\n"); + writer.print(" <owl:imports rdf:resource=\""+align.getOntology1URI().toString()+"\"/>"+NL); + writer.print(" <owl:imports rdf:resource=\""+align.getOntology2URI().toString()+"\"/>"+NL); + writer.print(" </owl:Ontology>"+NL+NL); try { for( Cell c : align ){ Object ob1 = c.getObject1(); Object ob2 = c.getObject2(); - if ( heterogeneous || + if ( heterogeneous || edoal || ( onto1.isClass( ob1 ) && onto2.isClass( ob2 ) ) || ( onto1.isDataProperty( ob1 ) && onto2.isDataProperty( ob2 ) ) || ( onto1.isObjectProperty( ob1 ) && onto2.isObjectProperty( ob2 ) ) || - ( onto1.isIndividual( ob1 ) && onto2.isIndividual( ob2 ) ) ) + ( onto1.isIndividual( ob1 ) && onto2.isIndividual( ob2 ) ) ) { c.accept( this ); - + } } //end for } catch ( OntowrapException owex ) { throw new AlignmentException( "Error accessing ontology", owex ); } - writer.print("</rdf:RDF>\n"); + writer.print("</rdf:RDF>"+NL); } public void visit( Cell cell ) throws AlignmentException { - this.cell = cell; - Object ob1 = cell.getObject1(); - Object ob2 = cell.getObject2(); - URI u1; - try { - if ( cell.getRelation() instanceof SubsumedRelation ){ - u1 = onto2.getEntityURI( cell.getObject2() ); - } else { - u1 = onto1.getEntityURI( ob1 ); - } - if ( onto1.isClass( ob1 ) ) { - writer.print(" <owl:Class rdf:about=\""+u1+"\">\n"); - cell.getRelation().accept( this ); - writer.print(" </owl:Class>\n"); - } else if ( onto1.isDataProperty( ob1 ) ) { - writer.print(" <owl:DatatypeProperty rdf:about=\""+u1+"\">\n"); - cell.getRelation().accept( this ); - writer.print(" </owl:DatatypeProperty>\n"); - } else if ( onto1.isObjectProperty( ob1 ) ) { - writer.print(" <owl:ObjectProperty rdf:about=\""+u1+"\">\n"); - cell.getRelation().accept( this ); - writer.print(" </owl:ObjectProperty>\n"); - } else if ( onto1.isIndividual( ob1 ) ) { - writer.print(" <owl:Thing rdf:about=\""+u1+"\">\n"); - cell.getRelation().accept( this ); - writer.print(" </owl:Thing>\n"); + if ( cell.getId() != null ) writer.print(NL+NL+"<!-- "+cell.getId()+" -->"+NL); + if ( cell instanceof EDOALCell ) { + visit( (EDOALCell)cell ); + } else { + this.cell = cell; + Object ob1 = cell.getObject1(); + Object ob2 = cell.getObject2(); + URI u1; + try { + if ( cell.getRelation() instanceof SubsumedRelation ){ + u1 = onto2.getEntityURI( cell.getObject2() ); + } else { + u1 = onto1.getEntityURI( ob1 ); + } + if ( ob1 instanceof ClassExpression || onto1.isClass( ob1 ) ) { + writer.print(" <owl:Class rdf:about=\""+u1+"\">"+NL); + cell.getRelation().accept( this ); + writer.print(" </owl:Class>"+NL); + } else if ( ob1 instanceof PropertyExpression || onto1.isDataProperty( ob1 ) ) { + writer.print(" <owl:DatatypeProperty rdf:about=\""+u1+"\">"+NL); + cell.getRelation().accept( this ); + writer.print(" </owl:DatatypeProperty>"+NL); + } else if ( ob1 instanceof RelationExpression || onto1.isObjectProperty( ob1 ) ) { + writer.print(" <owl:ObjectProperty rdf:about=\""+u1+"\">"+NL); + cell.getRelation().accept( this ); + writer.print(" </owl:ObjectProperty>"+NL); + } else if ( ob1 instanceof InstanceExpression || onto1.isIndividual( ob1 ) ) { + writer.print(" <owl:Thing rdf:about=\""+u1+"\">"+NL); + cell.getRelation().accept( this ); + writer.print(" </owl:Thing>"+NL); + } + } catch ( OntowrapException owex ) { + throw new AlignmentException( "Error accessing ontology", owex ); } - } catch ( OntowrapException owex ) { - throw new AlignmentException( "Error accessing ontology", owex ); } } + public String getRelationName( LoadedOntology onto, Object ob, Relation rel ) { + try { + if ( rel instanceof EquivRelation ) { + if ( onto.isClass( ob ) ) { + return "owl:equivalentClass"; + } else if ( onto.isProperty( ob ) ) { + return "owl:equivalentProperty"; + } else if ( onto.isIndividual( ob ) ) { + return "owl:sameAs"; + } + } else if ( rel instanceof SubsumeRelation ) { + if ( onto.isClass( ob ) ) { + return "rdfs:subClassOf"; + } else if ( onto.isProperty( ob ) ) { + return "rdfs:subPropertyOf"; + } + } else if ( rel instanceof SubsumedRelation ) { + if ( onto.isClass( ob ) ) { + return "rdfs:subClassOf"; + } else if ( onto.isProperty( ob ) ) { + return "rdfs:subPropertyOf"; + } + } else if ( rel instanceof IncompatRelation ) { + if ( onto.isClass( ob ) ) { + return "rdfs:disjointFrom"; + } else if ( onto.isIndividual( ob ) ) { + return "owl:differentFrom"; + } + } + } catch ( OntowrapException owex ) {}; // return null anyway + return null; + } + public void visit( EquivRelation rel ) throws AlignmentException { Object ob2 = cell.getObject2(); - URI u2; - try { - u2 = onto2.getEntityURI( ob2 ); - if ( onto2.isClass( ob2 ) ) { - writer.print(" <owl:equivalentClass rdf:resource=\""+u2+"\"/>\n"); - } else if ( onto2.isDataProperty( ob2 ) ) { - writer.print(" <owl:equivalentProperty rdf:resource=\""+u2+"\"/>\n"); - } else if ( onto2.isObjectProperty( ob2 ) ) { - writer.print(" <owl:equivalentProperty rdf:resource=\""+u2+"\"/>\n"); - } else if ( onto2.isIndividual( ob2 ) ) { - writer.print(" <owl:sameAs rdf:resource=\""+u2+"\"/>\n"); + String owlrel = getRelationName( onto2, ob2, rel ); + if ( owlrel == null ) throw new AlignmentException( "Cannot express relation "+rel ); + if ( !edoal ) { + try { + writer.print(" <"+owlrel+" rdf:resource=\""+onto2.getEntityURI( ob2 )+"\"/>"+NL); + } catch ( OntowrapException owex ) { + throw new AlignmentException( "Error accessing ontology", owex ); + } + } else { + if ( ob2 instanceof InstanceId ) { + writer.print(" <"+owlrel+" rdf:resource=\""+((InstanceId)ob2).getURI()+"\"/>"+NL); + } else { + writer.println(" <"+owlrel+">"); + ((Expression)ob2).accept( this ); + writer.println(" </"+owlrel+">"); } - } catch ( OntowrapException owex ) { - throw new AlignmentException( "Error accessing ontology", owex ); } } public void visit( SubsumeRelation rel ) throws AlignmentException { Object ob2 = cell.getObject2(); - URI u2; + String owlrel = getRelationName( onto2, ob2, rel ); + if ( owlrel == null ) throw new AlignmentException( "Cannot express relation "+rel ); + if ( !edoal ) { try { - u2 = onto2.getEntityURI( ob2 ); - if ( onto1.isClass( ob2 ) ) { - writer.print(" <rdfs:subClassOf rdf:resource=\""+u2+"\"/>\n"); - } else if ( onto1.isDataProperty( ob2 ) ) { - writer.print(" <rdfs:subPropertyOf rdf:resource=\""+u2+"\"/>\n"); - } else if ( onto1.isObjectProperty( ob2 ) ) { - writer.print(" <rdfs:subPropertyOf rdf:resource=\""+u2+"\"/>\n"); - } + writer.print(" <"+owlrel+" rdf:resource=\""+onto2.getEntityURI( ob2 )+"\"/>"+NL); } catch ( OntowrapException owex ) { throw new AlignmentException( "Error accessing ontology", owex ); } + } else { + writer.println(" <"+owlrel+">"); + ((Expression)ob2).accept( this ); + writer.println(" </"+owlrel+">"); + } } public void visit( SubsumedRelation rel ) throws AlignmentException { Object ob1 = cell.getObject1(); - URI u1; + String owlrel = getRelationName( onto1, ob1, rel ); + if ( owlrel == null ) throw new AlignmentException( "Cannot express relation "+rel ); + if ( !edoal ) { try { - u1 = onto1.getEntityURI( ob1 ); - if ( onto1.isClass( ob1 ) ) { - writer.print(" <rdfs:subClassOf rdf:resource=\""+u1+"\"/>\n"); - } else if ( onto1.isDataProperty( ob1 ) ) { - writer.print(" <rdfs:subPropertyOf rdf:resource=\""+u1+"\"/>\n"); - } else if ( onto1.isObjectProperty( ob1 ) ) { - writer.print(" <rdfs:subPropertyOf rdf:resource=\""+u1+"\"/>\n"); - } + writer.print(" <"+owlrel+" rdf:resource=\""+onto1.getEntityURI( ob1 )+"\"/>"+NL); } catch ( OntowrapException owex ) { throw new AlignmentException( "Error accessing ontology", owex ); } + } else { + writer.println(" <"+owlrel+">"); + ((Expression)ob1).accept( this ); + writer.println(" </"+owlrel+">"); + } } public void visit( IncompatRelation rel ) throws AlignmentException { Object ob2 = cell.getObject2(); - URI u2; + String owlrel = getRelationName( onto2, ob2, rel ); + if ( owlrel == null ) throw new AlignmentException( "Cannot express relation "+rel ); + if ( !edoal ) { try { - u2 = onto2.getEntityURI( ob2 ); + writer.print(" <"+owlrel+" rdf:resource=\""+onto2.getEntityURI( ob2 )+"\"/>"+NL); } catch ( OntowrapException owex ) { throw new AlignmentException( "Cannot find entity URI", owex ); } - writer.print(" <owl:disjointWith rdf:resource=\""+u2+"\"/>\n"); + } else { + writer.println(" <"+owlrel+">"); + ((Expression)ob2).accept( this ); + writer.println(" </"+owlrel+">"); + } } public void visit( Relation rel ) throws AlignmentException { - // JE: I do not understand why I need this, - // but this seems to be the case... - try { - Method mm = null; - if ( Class.forName("fr.inrialpes.exmo.align.impl.rel.EquivRelation").isInstance(rel) ){ - mm = this.getClass().getMethod("visit", - new Class [] {Class.forName("fr.inrialpes.exmo.align.impl.rel.EquivRelation")}); - } else if (Class.forName("fr.inrialpes.exmo.align.impl.rel.SubsumeRelation").isInstance(rel) ) { - mm = this.getClass().getMethod("visit", - new Class [] {Class.forName("fr.inrialpes.exmo.align.impl.rel.SubsumeRelation")}); - } else if (Class.forName("fr.inrialpes.exmo.align.impl.rel.SubsumedRelation").isInstance(rel) ) { - mm = this.getClass().getMethod("visit", - new Class [] {Class.forName("fr.inrialpes.exmo.align.impl.rel.SubsumedRelation")}); - } else if (Class.forName("fr.inrialpes.exmo.align.impl.rel.IncompatRelation").isInstance(rel) ) { - mm = this.getClass().getMethod("visit", - new Class [] {Class.forName("fr.inrialpes.exmo.align.impl.rel.IncompatRelation")}); - } - if ( mm != null ) mm.invoke(this,new Object[] {rel}); - else { - if ( Class.forName("fr.inrialpes.exmo.align.impl.BasicRelation").isInstance(rel) ){ - Object ob2 = cell.getObject2(); - URI u2; - try { - u2 = onto2.getEntityURI( ob2 ); - if ( onto2.isIndividual( ob2 ) ) { // ob1 has been checked before - // It would be better to check that r is a relation of one of the ontologies by - // onto1.isObjectProperty( onto1.getEntity( new URI ( r ) ) ) - String r = ((BasicRelation)rel).getRelation(); - if ( r!=null && !r.equals("") ) - writer.print(" <"+r+" rdf:resource=\""+u2+"\"/>\n"); + if ( rel instanceof EDOALRelation ) visit( (EDOALRelation)rel ); + else { + // JE: I do not understand why I need this, + // but this seems to be the case... + try { + Method mm = null; + if ( Class.forName("fr.inrialpes.exmo.align.impl.rel.EquivRelation").isInstance(rel) ){ + mm = this.getClass().getMethod("visit", + new Class [] {Class.forName("fr.inrialpes.exmo.align.impl.rel.EquivRelation")}); + } else if (Class.forName("fr.inrialpes.exmo.align.impl.rel.SubsumeRelation").isInstance(rel) ) { + mm = this.getClass().getMethod("visit", + new Class [] {Class.forName("fr.inrialpes.exmo.align.impl.rel.SubsumeRelation")}); + } else if (Class.forName("fr.inrialpes.exmo.align.impl.rel.SubsumedRelation").isInstance(rel) ) { + mm = this.getClass().getMethod("visit", + new Class [] {Class.forName("fr.inrialpes.exmo.align.impl.rel.SubsumedRelation")}); + } else if (Class.forName("fr.inrialpes.exmo.align.impl.rel.IncompatRelation").isInstance(rel) ) { + mm = this.getClass().getMethod("visit", + new Class [] {Class.forName("fr.inrialpes.exmo.align.impl.rel.IncompatRelation")}); + } + if ( mm != null ) mm.invoke(this,new Object[] {rel}); + else { + if ( Class.forName("fr.inrialpes.exmo.align.impl.BasicRelation").isInstance(rel) ){ + try { + // This is only for individuals + Object ob2 = cell.getObject2(); + if ( onto2.isIndividual( ob2 ) ) { + // ob1 has been checked before + // It would be better to check that r is a relation of one of the ontologies by + // onto1.isObjectProperty( onto1.getEntity( new URI ( r ) ) ) + String r = ((BasicRelation)rel).getRelation(); + if ( r!=null && !r.equals("") ) { + URI u2 = onto2.getEntityURI( ob2 ); + writer.print(" <"+r+" rdf:resource=\""+u2+"\"/>"+NL); + } + } + } catch ( OntowrapException owex ) { + throw new AlignmentException( "Error accessing ontology", owex ); } - } catch ( OntowrapException owex ) { - throw new AlignmentException( "Error accessing ontology", owex ); } } + } catch (IllegalAccessException e) { + e.printStackTrace(); + } catch (ClassNotFoundException e) { + e.printStackTrace(); + } catch (NoSuchMethodException e) { + e.printStackTrace(); + } catch (InvocationTargetException e) { + e.printStackTrace(); } - } catch (IllegalAccessException e) { - e.printStackTrace(); - } catch (ClassNotFoundException e) { - e.printStackTrace(); - } catch (NoSuchMethodException e) { - e.printStackTrace(); - } catch (InvocationTargetException e) { - e.printStackTrace(); } }; + + public void visit( EDOALCell cell ) throws AlignmentException { + this.cell = cell; + toProcess = cell.getRelation(); + if ( ((EDOALRelation)toProcess).getDirection() != EDOALRelation.Direction.SUBSUMES + && ((EDOALRelation)toProcess).getDirection() != EDOALRelation.Direction.HASINSTANCE ) { + ((Expression)cell.getObject1()).accept( this ); + } else { + ((Expression)cell.getObject2()).accept( this ); + } + writer.print(NL); + } + + /** + * The current implementation is not satisfying: + * EDOALRelation is deconnected from Relation (for historical purposes) + * This is left this way because the complete relations should be reengineered + */ + public void visit( EDOALRelation o ) throws AlignmentException { + String relName; + boolean reversed = false; + Object ob2 = cell.getObject2(); + if ( o.getDirection() == EDOALRelation.Direction.EQUIVALENCE ) { + if ( ob2 instanceof ClassExpression ) { + relName = "owl:equivalentClass"; + } else if ( ob2 instanceof PropertyExpression || ob2 instanceof RelationExpression ) { + relName = "owl:equivalentProperty"; + } else if ( ob2 instanceof InstanceExpression ) { + relName = "owl:sameAs"; + } else throw new AlignmentException( "Equivalence relation cannot apply to "+o ); + } else if ( o.getDirection() == EDOALRelation.Direction.DISJOINTFROM ) { + if ( ob2 instanceof ClassExpression ) { + relName = "owl:disjointFrom"; + } else if ( ob2 instanceof InstanceExpression ) { + relName = "owl:differentFrom"; + } else throw new AlignmentException( "Disjointness relation cannot apply to "+o ); + } else if ( o.getDirection() == EDOALRelation.Direction.SUBSUMES ) { + reversed = true; + if ( ob2 instanceof ClassExpression ) { + relName = "owl:subClassOf"; + } else if ( ob2 instanceof PropertyExpression || ob2 instanceof RelationExpression ) { + relName = "owl:subPropertyOf"; + } else throw new AlignmentException( "Subsumption relation cannot apply to "+o ); + } else if ( o.getDirection() == EDOALRelation.Direction.SUBSUMEDBY ) { + if ( ob2 instanceof ClassExpression ) { + relName = "owl:subClassOf"; + } else if ( ob2 instanceof PropertyExpression || ob2 instanceof RelationExpression ) { + relName = "owl:subPropertyOf"; + } else throw new AlignmentException( "Subsumption relation cannot apply to "+o ); + } else if ( o.getDirection() == EDOALRelation.Direction.INSTANCEOF ) { + relName = "rdf:type"; + } else if ( o.getDirection() == EDOALRelation.Direction.HASINSTANCE ) { + reversed = true; + relName = "rdf:type"; + } else { + throw new AlignmentException( "Cannot deal with relation "+o ); + } + writer.print(" <"+relName+">"+NL); + increaseIndent(); + if ( reversed ) { + ((Expression)cell.getObject1()).accept( this ); + } else { + ((Expression)ob2).accept( this ); + } + decreaseIndent(); + writer.print(NL+" </"+relName+">"); + } + + // ******* EDOAL + + public void visit( Expression o ) throws AlignmentException { + if ( o instanceof ClassExpression ) visit( (ClassExpression)o ); + else if ( o instanceof RelationRestriction ) visit( (RelationRestriction)o ); + else if ( o instanceof PropertyRestriction ) visit( (PropertyRestriction)o ); + else if ( o instanceof ClassRestriction ) visit( (ClassRestriction)o ); + else if ( o instanceof PathExpression ) visit( (PathExpression)o ); + else if ( o instanceof PropertyExpression ) visit( (PropertyExpression)o ); + else if ( o instanceof InstanceExpression ) visit( (InstanceExpression)o ); + else if ( o instanceof RelationExpression ) visit( (RelationExpression)o ); + else throw new AlignmentException( "Cannot dispatch Expression "+o ); + } + + public void visit( final PathExpression p ) throws AlignmentException { + if ( p instanceof RelationExpression ) visit( (RelationExpression)p ); + else if ( p instanceof PropertyExpression ) visit( (PropertyExpression)p ); + else throw new AlignmentException( "Cannot dispatch PathExpression "+p ); + } + + public void visit( final ClassExpression e ) throws AlignmentException { + if ( e instanceof ClassId ) visit( (ClassId)e ); + else if ( e instanceof ClassConstruction ) visit( (ClassConstruction)e ); + else if ( e instanceof ClassRestriction ) visit( (ClassRestriction)e ); + else throw new AlignmentException( "Cannot dispatch ClassExpression "+e ); + } + + public void visit( final ClassId e ) throws AlignmentException { + if ( toProcess == null ) { + indentedOutput("<owl:Class "+SyntaxElement.RDF_ABOUT.print(DEF)+"=\""+e.getURI()+"\"/>"); + } else { + Relation toProcessNext = toProcess; + toProcess = null; + indentedOutput("<owl:Class "+SyntaxElement.RDF_ABOUT.print(DEF)+"=\""+e.getURI()+"\">"+NL); + increaseIndent(); + toProcessNext.accept( this ); + writer.print(NL); + decreaseIndent(); + indentedOutput("</owl:Class>"); + } + } + + public void visit( final ClassConstruction e ) throws AlignmentException { + Relation toProcessNext = toProcess; + toProcess = null; + final Constructor op = e.getOperator(); + String owlop = null; + // Very special treatment + if ( toProcessNext != null && e.getComponents().size() == 0 ) { + if ( op == Constructor.AND ) owlop = "http://www.w3.org/2002/07/owl#Thing"; + else if ( op == Constructor.OR ) owlop = "http://www.w3.org/2002/07/owl#Nothing"; + else if ( op == Constructor.NOT ) throw new AlignmentException( "Complement constructor cannot be empty"); + indentedOutput("<owl:Class "+SyntaxElement.RDF_ABOUT.print(DEF)+"=\""+owlop+"\">"+NL); + increaseIndent(); + toProcessNext.accept( this ); + writer.print(NL); + decreaseIndent(); + indentedOutput("</owl:Class>"); + } else { + if ( op == Constructor.AND ) owlop = "intersectionOf"; + else if ( op == Constructor.OR ) owlop = "unionOf"; + else if ( op == Constructor.NOT ) owlop = "complementOf"; + else throw new AlignmentException( "Unknown class constructor : "+op ); + if ( e.getComponents().size() == 0 ) { + if ( op == Constructor.AND ) indentedOutput("<owl:Thing/>"); + else if ( op == Constructor.OR ) indentedOutput("<owl:Nothing/>"); + else throw new AlignmentException( "Complement constructor cannot be empty"); + } else { + indentedOutput("<owl:Class>"+NL); + increaseIndent(); + indentedOutput("<owl:"+owlop); + if ( ( (op == Constructor.AND) || (op == Constructor.OR) ) ) + writer.print(" "+SyntaxElement.RDF_PARSETYPE.print(DEF)+"=\"Collection\""); + writer.print(">"+NL); + increaseIndent(); + for (final ClassExpression ce : e.getComponents()) { + writer.print(linePrefix); + ce.accept( this ); + writer.print(NL); + } + decreaseIndent(); + indentedOutput("</owl:"+owlop+">"+NL); + if ( toProcessNext != null ) { toProcessNext.accept( this ); writer.print(NL); } + decreaseIndent(); + indentedOutput("</owl:Class>"); + } + } + } + + public void visit(final ClassRestriction e) throws AlignmentException { + if ( e instanceof ClassValueRestriction ) visit( (ClassValueRestriction)e ); + else if ( e instanceof ClassTypeRestriction ) visit( (ClassTypeRestriction)e ); + else if ( e instanceof ClassDomainRestriction ) visit( (ClassDomainRestriction)e ); + else if ( e instanceof ClassOccurenceRestriction ) visit( (ClassOccurenceRestriction)e ); + else throw new AlignmentException( "Cannot dispatch ClassExpression "+e ); + } + + public void visit( final ClassValueRestriction c ) throws AlignmentException { + Relation toProcessNext = toProcess; + toProcess = null; + indentedOutput("<owl:Restriction>"+NL); + increaseIndent(); + indentedOutput("<owl:onProperty>"+NL); + increaseIndent(); + c.getRestrictionPath().accept( this ); + decreaseIndent(); + writer.print(NL); + indentedOutputln("</owl:onProperty>"); + ValueExpression ve = c.getValue(); + if ( ve instanceof Value ) { + indentedOutput("<owl:hasValue"); + if ( ((Value)ve).getType() != null ) { + writer.print( " rdf:datatype=\""+((Value)ve).getType()+"\"" ); + } + writer.print( ">"+((Value)ve).getValue()+"</owl:hasValue>"+NL); + } else if ( ve instanceof InstanceId ) { + indentedOutput("<owl:hasValue>"+NL); + increaseIndent(); + ve.accept( this ); + decreaseIndent(); + writer.print(NL); + indentedOutput("</owl:hasValue>"+NL); + } else throw new AlignmentException( "OWL does not support path constraints in hasValue : "+ve ); + if ( toProcessNext != null ) { toProcessNext.accept( this ); writer.print(NL); } + decreaseIndent(); + indentedOutput("</owl:Restriction>"); + } + + public void visit( final ClassTypeRestriction c ) throws AlignmentException { + Relation toProcessNext = toProcess; + toProcess = null; + indentedOutput("<owl:Restriction>"+NL); + increaseIndent(); + indentedOutput("<owl:onProperty>"+NL); + increaseIndent(); + c.getRestrictionPath().accept( this ); + writer.print(NL); + decreaseIndent(); + indentedOutput("</owl:onProperty>"+NL); + indentedOutput("<owl:allValuesFrom>"+NL); + increaseIndent(); + visit( c.getType() ); // JE2010 ?? + writer.print(NL); + decreaseIndent(); + indentedOutput("</owl:allValuesFrom>"+NL); + if ( toProcessNext != null ) { toProcessNext.accept( this ); writer.print(NL); } + decreaseIndent(); + indentedOutput("</owl:Restriction>"); + } + + public void visit( final ClassDomainRestriction c ) throws AlignmentException { + Relation toProcessNext = toProcess; + toProcess = null; + indentedOutput("<owl:Restriction>"+NL); + increaseIndent(); + indentedOutput("<owl:onProperty>"+NL); + increaseIndent(); + c.getRestrictionPath().accept( this ); + writer.print(NL); + decreaseIndent(); + indentedOutput("</owl:onProperty>"+NL); + if ( c.isUniversal() ) { + indentedOutput("<owl:allValuesFrom>"+NL); + } else { + indentedOutput("<owl:someValuesFrom>"+NL); + } + increaseIndent(); + c.getDomain().accept( this ); + writer.print(NL); + decreaseIndent(); + if ( c.isUniversal() ) { + indentedOutput("</owl:allValuesFrom>"+NL); + } else { + indentedOutput("</owl:someValuesFrom>"+NL); + } + if ( toProcessNext != null ) { toProcessNext.accept( this ); writer.print(NL); } + decreaseIndent(); + indentedOutput("</owl:Restriction>"); + } + + // TOTEST + public void visit( final ClassOccurenceRestriction c ) throws AlignmentException { + Relation toProcessNext = toProcess; + toProcess = null; + indentedOutput("<owl:Restriction>"+NL); + increaseIndent(); + indentedOutput("<owl:onProperty>"+NL); + increaseIndent(); + c.getRestrictionPath().accept( this ); + writer.print(NL); + decreaseIndent(); + indentedOutput("</owl:onProperty>"+NL); + String cardinality = null; + Comparator comp = c.getComparator(); + if ( comp == Comparator.EQUAL ) cardinality = "cardinality"; + else if ( comp == Comparator.LOWER ) cardinality = "maxCardinality"; + else if ( comp == Comparator.GREATER ) cardinality = "minCardinality"; + else throw new AlignmentException( "Unknown comparator : "+comp.getURI() ); + indentedOutput("<owl:"+cardinality+" rdf:datatype=\"&xsd;nonNegativeInteger\">"); + writer.print(c.getOccurence()); + writer.print("</owl:"+cardinality+">"+NL); + if ( toProcessNext != null ) { toProcessNext.accept( this ); writer.print(NL); } + decreaseIndent(); + indentedOutput("</owl:Restriction>"); + } + + public void visit(final PropertyExpression e) throws AlignmentException { + if ( e instanceof PropertyId ) visit( (PropertyId)e ); + else if ( e instanceof PropertyConstruction ) visit( (PropertyConstruction)e ); + else if ( e instanceof PropertyRestriction ) visit( (PropertyRestriction)e ); + else throw new AlignmentException( "Cannot dispatch ClassExpression "+e ); + } + + public void visit(final PropertyId e) throws AlignmentException { + if ( toProcess == null ) { + indentedOutput("<owl:DatatypeProperty "+SyntaxElement.RDF_ABOUT.print(DEF)+"=\""+e.getURI()+"\"/>"); + } else { + Relation toProcessNext = toProcess; + toProcess = null; + indentedOutput("<owl:DatatypeProperty "+SyntaxElement.RDF_ABOUT.print(DEF)+"=\""+e.getURI()+"\">"+NL); + increaseIndent(); + toProcessNext.accept( this ); + writer.print(NL); + decreaseIndent(); + indentedOutput("</owl:DatatypeProperty>"); + } + } + + /** + * OWL, and in particular OWL 2, does not allow for more Relation (ObjectProperty) + * and Property (DataProperty) constructor than owl:inverseOf + * It is thus imposible to transcribe our and, or and not constructors. + */ + public void visit(final PropertyConstruction e) throws AlignmentException { + Relation toProcessNext = toProcess; + toProcess = null; + indentedOutput("<owl:DatatypePropety>"+NL); + increaseIndent(); + final Constructor op = e.getOperator(); + String owlop = null; + // JE: FOR TESTING + //owlop = "FORTESTING("+op.name()+")"; + if ( owlop == null ) throw new AlignmentException( "Cannot translate property construction in OWL : "+op ); + indentedOutput("<owl:"+owlop); + if ( (op == Constructor.AND) || (op == Constructor.OR) || (op == Constructor.COMP) ) writer.print(" "+SyntaxElement.RDF_PARSETYPE.print(DEF)+"=\"Collection\""); + writer.print(">"+NL); + increaseIndent(); + if ( (op == Constructor.AND) || (op == Constructor.OR) || (op == Constructor.COMP) ) { + for ( final PathExpression pe : e.getComponents() ) { + writer.print(linePrefix); + pe.accept( this ); + writer.print(NL); + } + } else { + for (final PathExpression pe : e.getComponents()) { + pe.accept( this ); + writer.print(NL); + } + } + decreaseIndent(); + indentedOutput("</owl:"+owlop+">"+NL); + if ( toProcessNext != null ) { toProcessNext.accept( this ); writer.print(NL); } + decreaseIndent(); + indentedOutput("</owl:DatatypePropety>"); + } + + public void visit(final PropertyRestriction e) throws AlignmentException { + if ( e instanceof PropertyValueRestriction ) visit( (PropertyValueRestriction)e ); + else if ( e instanceof PropertyDomainRestriction ) visit( (PropertyDomainRestriction)e ); + else if ( e instanceof PropertyTypeRestriction ) visit( (PropertyTypeRestriction)e ); + else throw new AlignmentException( "Cannot dispatch ClassExpression "+e ); + } + + public void visit(final PropertyValueRestriction c) throws AlignmentException { + Relation toProcessNext = toProcess; + toProcess = null; + indentedOutput("<owl:DatatypeProperty>"+NL); + increaseIndent(); + indentedOutput("<rdfs:range>"+NL); + increaseIndent(); + indentedOutput("<rdfs:Datatype>"+NL); + increaseIndent(); + indentedOutput("<owl:oneOf>"+NL); + increaseIndent(); + // In EDOAL, this does only contain one value and is thus rendered as: + indentedOutput("<rdf:Description>"+NL); + increaseIndent(); + ValueExpression ve = c.getValue(); + if ( ve instanceof Value ) { + indentedOutput("<rdf:first"); + if ( ((Value)ve).getType() != null ) { + writer.print( " rdf:datatype=\""+((Value)ve).getType()+"\"" ); + } + writer.print( ">"+((Value)ve).getValue()+"</rdf:first>"+NL); + } else { + indentedOutput("<rdf:first>"+NL); + ve.accept( this ); + writer.print("</rdf:first>"+NL); + indentedOutput("<rdf:rest rdf:resource=\"http://www.w3.org/1999/02/22-rdf-syntax-ns#nil\"/>"+NL); + } + decreaseIndent(); + indentedOutput("</rdf:Description>"+NL); + // This is incorrect for more than one value... see the OWL: + /* + <rdfs:Datatype> + <owl:oneOf> + <rdf:Description> + <rdf:first rdf:datatype="&xsd;integer">1</rdf:first> + <rdf:rest> + <rdf:Description> + <rdf:first rdf:datatype="&xsd;integer">2</rdf:first> + <rdf:rest rdf:resource="http://www.w3.org/1999/02/22-rdf-syntax-ns#nil"/> + </rdf:Description> + </rdf:rest> + </rdf:Description> + </owl:oneOf> + </rdfs:Datatype> + */ + decreaseIndent(); + indentedOutput("</owl:oneOf>"+NL); + decreaseIndent(); + indentedOutput("</rdfs:Datatype>"+NL); + decreaseIndent(); + indentedOutput("</rdfs:range>"+NL); + if ( toProcessNext != null ) { toProcessNext.accept( this ); writer.print(NL); } + decreaseIndent(); + indentedOutput("</owl:DatatypeProperty>"); + } + + public void visit(final PropertyDomainRestriction c) throws AlignmentException { + Relation toProcessNext = toProcess; + toProcess = null; + indentedOutput("<owl:DatatypeProperty>"+NL); + increaseIndent(); + indentedOutput("<rdfs:domain>"+NL); + increaseIndent(); + c.getDomain().accept( this ); + writer.print(NL); + decreaseIndent(); + indentedOutput("</rdfs:domain>"+NL); + if ( toProcessNext != null ) { toProcessNext.accept( this ); writer.print(NL); } + decreaseIndent(); + indentedOutput("</owl:DatatypeProperty>"); + } + + public void visit(final PropertyTypeRestriction c) throws AlignmentException { + Relation toProcessNext = toProcess; + toProcess = null; + indentedOutput("<owl:DatatypeProperty>"+NL); + increaseIndent(); + indentedOutput("<rdfs:range>"+NL); + increaseIndent(); + c.getType().accept( this ); + decreaseIndent(); + indentedOutput("</rdfs:range>"+NL); + if ( toProcessNext != null ) { toProcessNext.accept( this ); writer.print(NL); } + decreaseIndent(); + indentedOutput("</owl:DatatypeProperty>"); + } + + public void visit( final RelationExpression e ) throws AlignmentException { + if ( e instanceof RelationId ) visit( (RelationId)e ); + else if ( e instanceof RelationRestriction ) visit( (RelationRestriction)e ); + else if ( e instanceof RelationConstruction ) visit( (RelationConstruction)e ); + else throw new AlignmentException( "Cannot dispatch ClassExpression "+e ); + } + + public void visit( final RelationId e ) throws AlignmentException { + if ( toProcess == null ) { + indentedOutput("<owl:ObjectProperty "+SyntaxElement.RDF_ABOUT.print(DEF)+"=\""+e.getURI()+"\"/>"); + } else { + Relation toProcessNext = toProcess; + toProcess = null; + indentedOutput("<owl:ObjectProperty "+SyntaxElement.RDF_ABOUT.print(DEF)+"=\""+e.getURI()+"\">"+NL); + increaseIndent(); + toProcessNext.accept( this ); + writer.print(NL); + decreaseIndent(); + indentedOutput("</owl:ObjectProperty>"); + } + } + + /** + * OWL, and in particular OWL 2, does not allow for more Relation (ObjectProperty) + * and Property (DataProperty) constructor than owl:inverseOf + * It is thus imposible to transcribe our and, or and not constructors. + * Moreover, they have no constructor for the symmetric, transitive and reflexive + * closure and the compositional closure (or composition) can only be obtained by + * defining a property subsumed by this closure through an axiom. + * It is also possible to rewrite the reflexive closures as axioms as well. + * But the transitive closure can only be obtained through subsuption. + */ + public void visit( final RelationConstruction e ) throws AlignmentException { + Relation toProcessNext = toProcess; + toProcess = null; + indentedOutput("<owl:ObjectProperty>"+NL); + increaseIndent(); + final Constructor op = e.getOperator(); + String owlop = null; + if ( op == Constructor.INVERSE ) owlop = "owl:inverseOf"; + // JE: FOR TESTING + //owlop = "FORTESTING("+op.name()+")"; + if ( owlop == null ) throw new AlignmentException( "Cannot translate relation construction in OWL : "+op ); + indentedOutput("<owl:"+owlop); + if ( (op == Constructor.OR) || (op == Constructor.AND) || (op == Constructor.COMP) ) writer.print(" "+SyntaxElement.RDF_PARSETYPE.print(DEF)+"=\"Collection\""); + writer.print(">"+NL); + increaseIndent(); + if ( (op == Constructor.AND) || (op == Constructor.OR) || (op == Constructor.COMP) ) { + for (final PathExpression re : e.getComponents()) { + writer.print(linePrefix); + re.accept( this ); + writer.print(NL); + } + } else { // NOT... or else: enumerate them + for (final PathExpression re : e.getComponents()) { + re.accept( this ); + writer.print(NL); + } + } + decreaseIndent(); + indentedOutput("</owl:"+owlop+">"+NL); + if ( toProcessNext != null ) { toProcessNext.accept( this ); writer.print(NL); } + decreaseIndent(); + indentedOutput("</owl:ObjectProperty>"); + } + + public void visit( final RelationRestriction e ) throws AlignmentException { + if ( e instanceof RelationCoDomainRestriction ) visit( (RelationCoDomainRestriction)e ); + else if ( e instanceof RelationDomainRestriction ) visit( (RelationDomainRestriction)e ); + else throw new AlignmentException( "Cannot dispatch ClassExpression "+e ); + } + + public void visit(final RelationCoDomainRestriction c) throws AlignmentException { + Relation toProcessNext = toProcess; + toProcess = null; + indentedOutput("<owl:ObjectProperty>"+NL); + increaseIndent(); + indentedOutput("<rdfs:range>"+NL); + increaseIndent(); + c.getCoDomain().accept( this ); + writer.print(NL); + decreaseIndent(); + indentedOutput("</rdfs:range>"+NL); + if ( toProcessNext != null ) { toProcessNext.accept( this ); writer.print(NL); } + decreaseIndent(); + indentedOutput("</owl:ObjectProperty>"); + } + + public void visit(final RelationDomainRestriction c) throws AlignmentException { + Relation toProcessNext = toProcess; + toProcess = null; + indentedOutput("<owl:ObjectProperty>"+NL); + increaseIndent(); + indentedOutput("<rdfs:domain>"+NL); + increaseIndent(); + c.getDomain().accept( this ); + writer.print(NL); + decreaseIndent(); + indentedOutput("</rdfs:domain>"+NL); + if ( toProcessNext != null ) { toProcessNext.accept( this ); writer.print(NL); } + decreaseIndent(); + indentedOutput("</owl:ObjectProperty>"); + } + + public void visit( final InstanceExpression e ) throws AlignmentException { + if ( e instanceof InstanceId ) visit( (InstanceId)e ); + else throw new AlignmentException( "Cannot handle InstanceExpression "+e ); + } + + public void visit( final InstanceId e ) throws AlignmentException { + if ( toProcess == null ) { + indentedOutput("<owl:Individual "+SyntaxElement.RDF_ABOUT.print(DEF)+"=\""+e.getURI()+"\"/>"); + } else { + Relation toProcessNext = toProcess; + toProcess = null; + indentedOutput("<owl:Individual "+SyntaxElement.RDF_ABOUT.print(DEF)+"=\""+e.getURI()+"\">"+NL); + increaseIndent(); + toProcessNext.accept( this ); + writer.print(NL); + decreaseIndent(); + indentedOutput("</owl:Individual>"); + } + } + + public void visit( final ValueExpression e ) throws AlignmentException { + if ( e instanceof InstanceExpression ) visit( (InstanceExpression)e ); + else if ( e instanceof PathExpression ) visit( (PathExpression)e ); + else if ( e instanceof Apply ) visit( (Apply)e ); + else if ( e instanceof Value ) visit( (Value)e ); + else throw new AlignmentException( "Cannot dispatch ClassExpression "+e ); + } + + // Unused: see ClassValueRestriction above + public void visit( final Value e ) throws AlignmentException { + } + + // OWL does not allow for function calls + public void visit( final Apply e ) throws AlignmentException { + throw new AlignmentException( "Cannot render function call in OWL "+e ); + } + + // Not implemented. We only ignore transformations in OWL + public void visit( final Transformation transf ) throws AlignmentException { + } + + /** + * Our Datatypes are only strings identifying datatypes. + * For OWL, they should be considered as built-in types because we do + * not know how to add other types. + * Hence we could simply have used a rdfs:Datatype="<name>" + * + * OWL offers further possiblities, such as additional owl:withRestriction + * clauses + */ + public void visit( final Datatype e ) { + indentedOutput("<owl:Datatype><owl:onDataType rdf:resource=\""+e.plainText()+"\"/></owl:Datatype>"); + } + + } diff --git a/src/fr/inrialpes/exmo/align/parser/RDFParser.java b/src/fr/inrialpes/exmo/align/parser/RDFParser.java index 5f0dca797b338f20895a97778d2ad7ce4cf39807..3c940b76007e64d114749f7ebad89098b4e2efcf 100644 --- a/src/fr/inrialpes/exmo/align/parser/RDFParser.java +++ b/src/fr/inrialpes/exmo/align/parser/RDFParser.java @@ -553,7 +553,7 @@ public class RDFParser { stmt = node.getProperty( (Property)SyntaxElement.COMPARATOR.resource ); if ( stmt == null ) throw new AlignmentException( "Required edoal:comparator property" ); URI id = getNodeId( stmt.getResource() ); - if ( id != null ) comp = new Comparator( id ); + if ( id != null ) comp = Comparator.getComparator( id ); else throw new AlignmentException("edoal:comparator requires an URI"); if ( rdfType.equals( SyntaxElement.OCCURENCE_COND.resource ) ) { stmt = node.getProperty( (Property)SyntaxElement.VALUE.resource ); @@ -681,7 +681,7 @@ public class RDFParser { if ( stmt == null ) throw new AlignmentException( "Required edoal:comparator property" ); URI id = getNodeId( stmt.getResource() ); if ( id == null ) throw new AlignmentException("edoal:comparator requires and URI"); - Comparator comp = new Comparator( id ); + Comparator comp = Comparator.getComparator( id ); stmt = node.getProperty( (Property)SyntaxElement.VALUE.resource ); if ( stmt == null ) throw new AlignmentException( "Required edoal:value property" ); ValueExpression v = parseValue( stmt.getObject() ); diff --git a/test/src/EDOALExportTest.java b/test/src/EDOALExportTest.java index a4f445b5630d7564320f90c1ba72309104b0754c..2640a478dc837c5756ca704006a014ca8baa62fd 100644 --- a/test/src/EDOALExportTest.java +++ b/test/src/EDOALExportTest.java @@ -35,9 +35,11 @@ import org.semanticweb.owl.align.Alignment; import org.semanticweb.owl.align.Visitable; import fr.inrialpes.exmo.align.impl.renderer.RDFRendererVisitor; +import fr.inrialpes.exmo.align.impl.renderer.OWLAxiomsRendererVisitor; import fr.inrialpes.exmo.align.impl.Annotations; import fr.inrialpes.exmo.align.impl.Namespace; import fr.inrialpes.exmo.align.impl.edoal.EDOALAlignment; +import fr.inrialpes.exmo.align.parser.AlignmentParser; import fr.inrialpes.exmo.ontowrap.Ontology; import fr.inrialpes.exmo.ontowrap.BasicOntology; @@ -93,7 +95,6 @@ import fr.inrialpes.exmo.align.impl.edoal.Value; import fr.inrialpes.exmo.align.impl.edoal.Datatype; import fr.inrialpes.exmo.align.impl.edoal.Comparator; - /** * These tests corresponds to the tests presented in the examples/omwg directory */ @@ -127,6 +128,50 @@ public class EDOALExportTest { return stream.toString(); } + // Load the full test ==> break because not all can be rendered + @Test(expectedExceptions = AlignmentException.class, groups = { "full", "omwg", "raw" }, dependsOnMethods = {"setUp"}) + public void testOWLRendering0() throws Exception { + AlignmentParser aparser = new AlignmentParser( 0 ); + aparser.initAlignment( null ); + Alignment alignment = aparser.parse( "file:examples/omwg/total.xml" ); + assertNotNull( alignment ); + // Print it in a string + ByteArrayOutputStream stream = new ByteArrayOutputStream(); + PrintWriter writer = new PrintWriter ( + new BufferedWriter( + new OutputStreamWriter( stream, "UTF-8" )), true); + AlignmentVisitor renderer = new OWLAxiomsRendererVisitor( writer ); + alignment.render( renderer ); + } + + // Load the stripped down test ==> it loads + // This cannot be passed to an OWL parser because no typechecking has been done + // This is only a syntactic test + @Test(groups = { "full", "omwg", "raw" }, dependsOnMethods = {"testOWLRendering0"}) + public void testOWLRendering1() throws Exception { + AlignmentParser aparser = new AlignmentParser( 0 ); + aparser.initAlignment( null ); + Alignment alignment = aparser.parse( "file:examples/omwg/total-owlable.xml" ); + assertNotNull( alignment ); + // Print it in a string + ByteArrayOutputStream stream = new ByteArrayOutputStream(); + PrintWriter writer = new PrintWriter ( + new BufferedWriter( + new OutputStreamWriter( stream, "UTF-8" )), true); + /* + OutputStream stream = new FileOutputStream( "/tmp/total.owl" ); + PrintWriter writer = new PrintWriter ( + new BufferedWriter( + new OutputStreamWriter( stream, "UTF-8" )), true); + */ + AlignmentVisitor renderer = new OWLAxiomsRendererVisitor( writer ); + alignment.render( renderer ); + writer.flush(); + writer.close(); + String str1 = stream.toString(); + assertEquals( str1.length(), 12099 ); + } + @Test(groups = { "full", "omwg", "raw" }, dependsOnMethods = {"setUp"}) public void testExportPath() throws Exception { /* diff --git a/test/src/EDOALParserTest.java b/test/src/EDOALParserTest.java index 30f1d75c0308b27e9e681004be941744ba9a8e61..6b6e2138c6f12f6a2d3b34d222f57b4234e82718 100644 --- a/test/src/EDOALParserTest.java +++ b/test/src/EDOALParserTest.java @@ -84,14 +84,15 @@ public class EDOALParserTest { aparser1 = new AlignmentParser( 0 ); aparser1.initAlignment( null ); //System.err.println( str1 ); - alignment = aparser1.parseString( str1 ); + Alignment al = aparser1.parseString( str1 ); + assertEquals( alignment.nbCells(), al.nbCells() ); // Print it in another string stream = new ByteArrayOutputStream(); writer = new PrintWriter ( new BufferedWriter( new OutputStreamWriter( stream, "UTF-8" )), true); renderer = new RDFRendererVisitor( writer ); - alignment.render( renderer ); + al.render( renderer ); writer.flush(); writer.close(); String str2 = stream.toString();