]> gerrit.simantics Code Review - simantics/interop.git/blob - org.simantics.xml.sax/src/org/simantics/xml/sax/OntologyGenerator.java
Several updates to interoperability.
[simantics/interop.git] / org.simantics.xml.sax / src / org / simantics / xml / sax / OntologyGenerator.java
1 package org.simantics.xml.sax;
2
3 import java.io.FileNotFoundException;
4 import java.io.PrintWriter;
5 import java.io.StringWriter;
6 import java.util.LinkedHashSet;
7 import java.util.List;
8 import java.util.Set;
9
10 import javax.xml.namespace.QName;
11
12 import org.simantics.utils.datastructures.BijectionMap;
13 import org.simantics.xml.sax.SchemaConversionBase.Inheritance;
14 import org.simantics.xml.sax.SchemaConversionBase.RefType;
15 import org.simantics.xml.sax.SchemaObject.ObjectType;
16 import org.simantics.xml.sax.configuration.AttributeComposition;
17 import org.simantics.xml.sax.configuration.IDReference;
18 import org.w3._2001.xmlschema.Annotated;
19 import org.w3._2001.xmlschema.Attribute;
20 import org.w3._2001.xmlschema.AttributeGroup;
21 import org.w3._2001.xmlschema.Element;
22 import org.w3._2001.xmlschema.LocalComplexType;
23 import org.w3._2001.xmlschema.LocalSimpleType;
24 import org.w3._2001.xmlschema.NamedAttributeGroup;
25 import org.w3._2001.xmlschema.NamedGroup;
26 import org.w3._2001.xmlschema.Schema;
27 import org.w3._2001.xmlschema.SimpleType;
28
29 //public class OntologyGenerator extends SchemaConversionBase {
30 public class OntologyGenerator implements SchemaConversionComponent {
31         SchemaConversionBase base;
32         
33         public OntologyGenerator(SchemaConverter converter, SchemaConversionBase base) {
34                 this.base = base;
35                 this.converter = converter;
36                 this.schema = base.schema;
37                 this.ontologyUri = base.ontologyURI;
38                 this.className = base.className;                
39         }
40
41         String ontRoot = "ONT.";
42         String commentTag = "//";
43         
44         Schema schema;
45         String ontologyUri;
46         String className;
47         
48         SchemaConverter converter;
49         
50         PrintWriter writer = null;
51         
52         public void createOntology() throws FileNotFoundException {
53                 StringWriter stringWriter = null;
54                 if (converter.getOntologyFile() == null) {
55                         stringWriter = new StringWriter();
56                         writer = new PrintWriter(stringWriter);
57                 } else {
58                         writer = new PrintWriter(converter.getOntologyFile());
59                 }
60         
61                 handle();
62                 
63                 writer.flush();
64                 writer.close();
65                 if (stringWriter != null)
66                         System.out.println(stringWriter.toString());
67         }
68         
69         protected void handle() {
70                 ontRoot = converter.shortName;
71
72                 for (String s : converter.getHeader()) {
73                         writer.println(commentTag + " " + s);   
74                 }
75                 writer.println();
76                 writer.println("L0 = <http://www.simantics.org/Layer0-1.1>");
77                 writer.println("XML = <http://www.simantics.org/XML-1.0>");
78                 writer.println();
79                 if (converter.isPrimary()) {
80                 writer.println(ontRoot + " = <" + ontologyUri +"> : L0.Ontology");
81                 writer.println("   @L0.new");
82                 writer.println("   L0.HasResourceClass \"" + className +"\"");
83                 } else {
84                 writer.println(ontRoot + " = <" + ontologyUri +">");
85                 }
86                 writer.println();
87                 writer.println();
88                 
89                 ontRoot += ".";
90                 writer.println(ontRoot+"SimpleTypes : L0.Library");
91                 writer.println(ontRoot+"ComplexTypes : L0.Library");
92                 writer.println(ontRoot+"AttributeGroups : L0.Library");
93                 writer.println();
94                 writer.println(commentTag + " Interpreted from schema");
95                 writer.println();
96                         
97                 base.handle(this);
98         }
99                 
100         protected String getType(QName qtype, String rel) {
101                 String ontType = base.getL0TypeFromPrimitiveType(qtype);
102                 if (ontType != null)
103                         return ontType;
104                 else {
105                         if (base.isComplexTypeRef(qtype.getLocalPart()))
106                                 return getName(base.getComplexType(qtype), rel);
107                         else if (base.isSimpleTypeRef(qtype.getLocalPart()))
108                                 return getName(base.getSimpleType(qtype), rel);
109                         else if (base.isElementRef(qtype.getLocalPart()))
110                                 return getName(base.getElement(qtype), rel);
111                 }
112                 throw new RuntimeException("Reference to unknown type " + qtype.getLocalPart());
113         }
114         
115         public String getSimpleTypePrefix() {
116                 return "SimpleTypes.";
117         }
118         
119         public String getComplexTypePrefix() {
120                 return "ComplexTypes.";
121         }
122         
123         public String getAttributeGroupPrefix() {
124                 return "AttributeGroups.";
125         }
126         
127         public String handleChoice(SchemaObject parent, SchemaElement indicator, java.util.List<SchemaElement> elements, String name) {
128                 boolean single = true;
129                 for (SchemaElement e : elements) {
130                         if (e.getRestriction().many()) {
131                                 single = false;
132                                 break;
133                         }
134                 }
135                 String relationName = getName(parent)+".has"+name;
136                 writer.print(relationName);
137                 writer.print(" <R XML.hasElement");
138                 writer.println();
139                 
140                 if (!single) {
141                         String elementListType = getName(parent) + "." + name + "List";
142                         writer.println(elementListType + " <T XML.ElementList");
143                         writer.println(relationName + "List <R XML.hasElementList : L0.FunctionalRelation");
144                         writer.println("   --> " + elementListType);
145                 }
146                 
147                 return relationName;
148         };
149         
150         
151         
152         @Override
153         public void handleIndicator(SchemaObject parent, SchemaElement indicator, SchemaElement element, String refName, RefType refType, String baseRelationName) {
154                 if (refType != RefType.Element) {
155                         QName referenceType = null;
156                         if (refType == RefType.Type) {
157                                 referenceType = element.getElement().getType();
158                                 //refName = element.getElement().getName()
159                                 SchemaObject eObj = base.getElement(element.getElement());//base.elements.get(element.getElement());
160                                 if (refName == null)
161                                         refName = eObj.getName();
162                         } else {
163                                 referenceType = element.getElement().getRef();
164                                 if (refName == null)
165                                         refName = referenceType.getLocalPart();
166                         }
167                         String type = base.getL0TypeFromPrimitiveType(referenceType);
168                         SchemaObject obj = null;
169                         if (type == null) {
170                                 obj = base.getWithName(referenceType);
171                                 writer.print(getName(parent)+".has"+refName + " <R XML.hasElement <R " +  getName(obj,"has"));
172                                 if (baseRelationName != null) writer.print(" <R " + baseRelationName);
173                                 writer.println();
174                         } else {
175                                 writer.print(getName(parent)+".has"+refName + " <R XML.hasElement");
176                                 if (baseRelationName != null) writer.print(" <R " + baseRelationName);
177                                 writer.println();
178                                 writer.println("   --> " + getType(referenceType, ""));
179                         }
180                         
181                         if (base.useElementList(parent, indicator,element, refType == RefType.Reference, refName, referenceType)) {
182                                 
183                                 if (type == null) {
184                                         writer.println(getName(parent)+"."+refName + "List <T XML.ElementList");
185                                         writer.println(getName(parent)+".has"+refName + "List <R " +  getName(obj,"has")+"List : L0.FunctionalRelation");
186                                 } else {
187                                         writer.println(getName(parent)+"."+refName + "List <T XML.ElementList");
188                                         writer.println(getName(parent)+".has"+refName + "List <R XML.hasElementList : L0.FunctionalRelation");  
189                                 }
190                         }
191                 } else {
192                         Element attrs = element.getElement();
193                         SchemaObject obj = base.getWithObj(parent, attrs);
194                         if (refName == null)
195                                 refName = obj.getName();
196                         
197                         writer.print(getName(parent)+".has"+refName + " <R " + getName(obj,"has"));
198                         if (baseRelationName != null) writer.print(" <R " + baseRelationName);
199                         writer.println();
200                         writer.println("   --> " + getName(obj));
201                         if (base.useElementList(parent, indicator,element, false, refName, new QName(obj.getName()))) {
202                                 writer.println(getName(parent)+"."+refName + "List <T XML.ElementList");
203                                 writer.println(getName(parent)+".has"+refName + "List <R " +  getName(obj,"has")+"List : L0.FunctionalRelation");
204                         }
205                 }
206                 
207         }
208         
209         @Override
210         public void handleIndicator(SchemaObject parent, SchemaElement indicator, SchemaElement any) {
211                 
212         }
213         
214         @Override
215         public void handle(SchemaObject parent, NamedGroup attribute) {
216                 // TODO Auto-generated method stub
217                 
218         }
219                 
220         @Override
221         public void handle(SchemaObject parent, Attribute attribute) {
222                 String name = attribute.getName();
223                 QName primitiveType = attribute.getType();
224                 LocalSimpleType simpleType = attribute.getSimpleType();
225                 QName ref = attribute.getRef();
226                 
227                 String relationName;
228                 String relationType;
229                 if (name != null) {
230                         relationName = ontRoot+"has"+name;
231                         if (parent != null)
232                                 relationName = getName(parent)+".has"+name;
233                         relationType = "XML.hasAttribute";
234                 }
235                 else if (ref != null && parent != null) {
236                         relationName = getName(parent)+".has"+ref.getLocalPart();
237                         relationType = ontRoot+"has"+ref.getLocalPart();
238                 } else {
239                         throw new RuntimeException();
240                 }
241                 boolean id = false;
242                 String ontType = null;
243                 if (primitiveType != null) {
244                         ontType = base.getL0TypeFromPrimitiveType(primitiveType);
245                         if (ontType != null) {
246                                 id = base.getTypeEntry(primitiveType).id;
247                                 if (id)
248                                         relationType = "XML.hasID";
249                         } else {
250                                 
251                         }
252                 } else if (simpleType != null){
253 //                      Restriction restriction = simpleType.getRestriction();
254 //                      if (restriction == null || simpleType.getUnion() != null || simpleType.getName() != null || simpleType.getId() != null)
255 //                              throw new RuntimeException();
256 //                      QName base = restriction.getBase();
257                         QName base = this.base.getSimpleTypeBase(simpleType);
258                         
259                         
260                         ontType = this.base.getL0TypeFromPrimitiveType(base);
261                         
262 //                      for (Object facetWrap : restriction.getFacets()) {
263 //                              JAXBElement<?> element = (JAXBElement<?>)facetWrap;
264 //                              QName elementName = element.getName();
265 //                              Facet facet = (Facet)element.getValue();        
266 //                      }
267                 }
268                         
269                 
270                 
271                 writer.println(relationName+ " <R " + relationType + ": L0.FunctionalRelation");
272                 if (id) {
273                         // no need to add range restriction
274                 } else if (ontType != null) {
275                         writer.println("   --> " + ontType);
276                 } else if (primitiveType != null) {
277                         writer.println("   <R " + getType(primitiveType, "has"));
278                 }
279         }
280         
281         @Override
282         public void handleAttributes(SchemaObject simpleTypeObj) {
283 //              SchemaObject parent = simpleTypeObj.getParent();
284 //              SimpleType simpleType = simpleTypeObj.getSimpleType();
285 //              Restriction restriction = simpleType.getRestriction();
286 //              QName base = restriction.getBase();
287 //              String ontType = getL0TypeFromPrimitiveType(base);
288         }
289         
290         @Override
291         public void handle(SchemaObject parent, AttributeGroup attributeGroup) {
292                 if (parent == null) {
293                         NamedAttributeGroup group = (NamedAttributeGroup)attributeGroup;
294                         writer.println(ontRoot+getAttributeGroupPrefix()+group.getName()+ " <T XML.AttributeGroup");
295                         SchemaObject obj = new SchemaObject(parent,attributeGroup);
296                         for (Annotated annotated : group.getAttributeOrAttributeGroup()) {
297                                 if (annotated instanceof Attribute) {
298                                         //handle(getAttributeGroupPrefix()+group.getName(),(Attribute)annotated);
299                                         handle(obj,(Attribute)annotated);
300                                 } else if (annotated instanceof AttributeGroup) {
301                                         handle(obj,(AttributeGroup)annotated);
302                                         //throw new RuntimeException("Cannot handle nested attribute groups");
303                                 }
304                         }
305                 } else {
306                         writer.println(getName(parent) +" L0.Inherits " + ontRoot + getAttributeGroupPrefix() + attributeGroup.getRef().getLocalPart());
307                 }
308                 
309         }
310         
311         @Override
312         public void handleAttributeComposition(SchemaObject parent, AttributeComposition composition, BijectionMap<org.simantics.xml.sax.configuration.Attribute, Annotated> attributes) {
313                 Attribute compositionAttribute = new Attribute();
314                 compositionAttribute.setName(composition.getName());
315                 QName type = new QName(SchemaConversionBase.CONVERSION_NS, composition.getType());
316                 compositionAttribute.setType(type);
317                 handle(parent, compositionAttribute);
318         }
319         
320         @Override
321         public void handleSimpleType(SchemaObject parent, SchemaObject simpleTypeObj) {
322                 SimpleType simpleType = simpleTypeObj.getSimpleType();
323                 String name = simpleType.getName();
324                 
325                 org.w3._2001.xmlschema.List list = simpleType.getList();
326                 if (list != null) {
327                         // TODO : process restriction in lists
328                         String relationName = getName(simpleTypeObj, "has");
329                         writer.println(relationName+ " <R XML.hasAttribute : L0.FunctionalRelation");
330                         
331                         String ontType = base.getL0Type(new QName(SchemaConversionBase.SCHEMA_NS, "string"));
332                         writer.println("   --> " + ontType);
333                 } else {
334                         QName base = this.base.getSimpleTypeBase(simpleType);
335                         writer.println(getName(simpleTypeObj) + " <T " + getType(base, ""));
336                         
337                         String relationName = getName(simpleTypeObj, "has");
338                         
339                         writer.println(relationName+ " : L0.FunctionalRelation");
340                         writer.println("   --> " + getName(simpleTypeObj));
341                         
342 //                      Restriction restriction = simpleType.getRestriction();
343 //                      if (restriction != null) {
344 //                              
345 //                              QName base = restriction.getBase();
346 //                              String ontType = getL0Type(base);
347 //                              writer.println("   --> " + ontType);
348 //                      } else if (simpleType.getId() != null) {
349 //                              throw new RuntimeException(simpleType.getName() + " restriction error");
350 //                      } else if (simpleType.getUnion() != null) {
351 //                              Union union = simpleType.getUnion();
352 //                              String ontType = null;
353 //                              if (union.getMemberTypes().size() > 0) {
354 //                                      for (QName type : union.getMemberTypes()) {
355 //                                              String sType = null;
356 //                                              TypeEntry entry = getTypeEntry(type);
357 //                                              if (entry == null) {
358 //                                                      SchemaObject obj = simpleTypeName.get(type.getLocalPart());
359 //                                                      Inheritance inheritance = new Inheritance("");
360 //                                                      getAtomicTypeInheritance(type, obj, inheritance);
361 //                                                      sType = inheritance.atomicType.l0Type;
362 //                                              } else {
363 //                                                      sType = entry.l0Type;
364 //                                              }
365 //                                              if (ontType == null)
366 //                                                      ontType = sType;
367 //                                              else if (!ontType.equals(sType))
368 //                                                      throw new RuntimeException(simpleType.getName() + " union has incompatible member types");
369 //                                      }
370 //                              } else {
371 //                                      if (union.getSimpleType().size() == 0)
372 //                                              throw new RuntimeException(simpleType.getName() + " union error");
373 //                                      for (SimpleType s : union.getSimpleType()) {
374 //                                              if (restriction == null)
375 //                                                      restriction = s.getRestriction();
376 //                                              else  {
377 //                                                      Restriction r = s.getRestriction();
378 //                                                      if (!r.getBase().equals(restriction.getBase()))
379 //                                                              throw new RuntimeException(simpleType.getName() + " union has incompatible restriction bases");
380 //                                              }
381 //                                      }
382 //                                      QName base = restriction.getBase();
383 //                                      ontType = getL0Type(base);
384 //                              }
385 //                              writer.println("   --> " + ontType);
386 //                      } else {
387 //                              throw new RuntimeException(simpleType.getName() + " restriction error");
388 //                      }
389                         
390                 }
391         }
392         
393         @Override
394         public void handleComplexType(SchemaObject topLevelComplexType) {
395                 String name = getName(topLevelComplexType);
396 //              if (topLevelComplexType.getName().equals("Reference"))
397 //                      System.out.println();
398                 
399 //              String baseType = "XML.ComplexType";
400 //
401 //              QName base = getComplexTypeBase(topLevelComplexType.getComplexType());
402 //              if (base != null) {
403 //                      baseType = getType(base);
404 //              }
405 //              base = getSimpleTypeBase(topLevelComplexType.getSimpleType());
406 //              if (base != null) {
407 //                      baseType = getType(base);
408 //              }
409                 Inheritance inheritance = base.getInheritance(topLevelComplexType);
410                 
411 //              writer.println(name+ " <T "+baseType);
412                 
413                 // Type definition
414                 writer.println(name+ " <T " + inheritance.baseClass);
415                 writer.println(name + "List <T XML.ElementList");
416                 
417                 // Access relations
418                 String relationName = getName(topLevelComplexType,"has");
419                 writer.println(relationName+ " <R XML.hasComplexType");
420                 writer.println("   --> " + name);
421                 writer.println(relationName+ "List <R XML.hasElementList");
422                 writer.println("   --> " + name + "List");
423                 writer.println();
424                 
425                 // Attributes 
426 //              if (!baseType.equals(inheritance.baseClass))
427 //                      System.out.println();
428                 //super.handleComplexType(topLevelComplexType);
429                 base.handleComplexTypeAttributes(topLevelComplexType);
430                 base.handleComplexTypeExtension(topLevelComplexType);
431                 base.handleExtensionAttributes(topLevelComplexType);
432                 writer.println();
433         }
434         
435         @Override
436         public void handleElement(SchemaObject elementObj) {
437                 Element element = elementObj.getElement();
438                 String name = getName(elementObj);//element.getName();
439                 
440                 if ("Text".equals(name))
441                         System.out.println();
442                 
443                 String type = "XML.Element";
444                 Set<String> types = new LinkedHashSet<String>();
445                 if (element.getType() != null) {
446                         types.add(getType(element.getType(), ""));
447                 }
448                 QName base = this.base.getElementBase(element);
449                 if (base != null) {
450                         if (base.getNamespaceURI().equals(SchemaConversionBase.SCHEMA_NS)) {
451                                 String l0Type = this.base.getL0Type(base);
452                                 if (l0Type == null)
453                                         throw new RuntimeException("Cannot get L0 type for " + base.getLocalPart());
454                                 types.add(l0Type);
455                         } else if (this.base.isElementRef(base.getLocalPart()))
456                                 types.add(ontRoot+base.getLocalPart());
457                         else
458                                 types.add(ontRoot+getComplexTypePrefix()+base.getLocalPart());
459                 }
460                 QName substitution = element.getSubstitutionGroup();
461                 if (substitution != null) {
462                         if (this.base.isElementRef(substitution.getLocalPart()))
463                                 types.add(ontRoot+substitution.getLocalPart());
464                         else
465                                 types.add( ontRoot+getComplexTypePrefix()+substitution.getLocalPart());
466                 }
467                 for (String t : types) {
468                         type += " <T " + t;
469                 }
470
471                 String relationName =  getName(elementObj,"has");//ontRoot+"has"+name;
472 //              if (elementObj.getParent() != null) {
473 //                      //relationName = ontRoot+getComplexTypePrefix()+"has"+name.substring(getComplexTypePrefix().length());
474 //                      relationName = ontRoot+getName(elementObj.getParent()) + "has"+element.getName();
475 //              }
476                 writer.println(relationName+ " <R XML.hasElement");
477                 writer.println(relationName+ "List <R XML.hasElementList");
478                 
479                 writer.println(name+ " <T "+type);
480                 
481                 LocalComplexType complexType = element.getComplexType();
482                 LocalSimpleType simpleType = element.getSimpleType();
483                 
484                 if (complexType != null) {
485                         SchemaObject complexTypeObj = this.base.getComplexType(complexType);
486                         this.base.handleElementComplexTypeAttributes(complexTypeObj);
487                         this.base.handleComplexTypeExtension(complexTypeObj);
488                 } else if (simpleType != null) {
489                         SchemaObject simpleTypeObj = this.base.getSimpleType(simpleType);
490                         this.base.handleElementSimpleTypeAttributes(simpleTypeObj);
491                 }
492                 
493                 List<IDReference> references = this.base.getIDReferences(element);
494         
495                 for (IDReference ref : references) {
496                         writer.println(name+"."+ref.getReference().getName()+ " <R XML.hasReference");
497                 }
498                 
499                 writer.println();
500         }
501         
502         @Override
503         public String getBaseClass(ObjectType type) {
504                 if (type == ObjectType.ELEMENT)
505                         return "XML.Element";
506                 if (type == ObjectType.COMPLEX_TYPE)
507                         return "XML.ComplexType";
508                 throw new RuntimeException("ObjectType " + type + " has no base class");
509         }
510         
511         @Override
512         public String getName(SchemaObject obj) {
513                 if (obj.getParent() == null) {
514                         switch (obj.getType()) {
515                         case COMPLEX_TYPE:
516                                 return ontRoot+getComplexTypePrefix()+obj.getName();
517                         case ELEMENT:
518                                 return ontRoot+obj.getName();
519                         case ATTRIBUTE_GROUP:
520                                 return ontRoot+getAttributeGroupPrefix()+obj.getName();
521                         case SIMPLE_TYPE:
522                                 return ontRoot+getSimpleTypePrefix()+obj.getName();
523                         }
524                 } else {
525                         SchemaObject o = obj;
526                         SchemaObject prev = null;
527                         String name = "";
528                         while (o != null){
529                                 if (o.getName() != null)
530                                         name = o.getName()+"."+name;
531                                 prev = o;
532                                 o = o.getParent();
533                         }
534                         name = name.substring(0, name.length()-1);
535                         switch (prev.getType()) {
536                         case COMPLEX_TYPE:
537                                 return ontRoot+getComplexTypePrefix()+name;
538                         case ELEMENT:
539                                 return ontRoot+name;
540                         case ATTRIBUTE_GROUP:
541                                 return ontRoot+getAttributeGroupPrefix()+name;
542                         case SIMPLE_TYPE:
543                                 return ontRoot+getSimpleTypePrefix()+name;
544                         }
545                 }
546                 throw new RuntimeException();
547                 
548         }
549         
550         public String getName(SchemaObject parent, SchemaElement e, String rel) {
551                 QName ref = e.getElement().getRef();
552                 if (ref != null) {
553                         return converter.getShortName(ref.getNamespaceURI()) + rel + ref.getLocalPart();
554                 }
555                 else {
556                         return getName(parent, "") + "." + rel + e.getElement().getName();
557                 }
558         }
559         
560         public String getName(SchemaObject obj, String rel) {
561                 if (obj.getParent() == null) {
562                         switch (obj.getType()) {
563                         case COMPLEX_TYPE:
564                                 return ontRoot+getComplexTypePrefix()+rel+obj.getName();
565                         case ELEMENT:
566                                 return ontRoot+rel+obj.getName();
567                         case ATTRIBUTE_GROUP:
568                                 return ontRoot+getAttributeGroupPrefix()+rel+obj.getName();
569                         case SIMPLE_TYPE:
570                                 return ontRoot+getSimpleTypePrefix()+rel+obj.getName();
571                         }
572                 } else {
573                         SchemaObject o = obj;
574                         SchemaObject prev = null;
575                         String name = "";
576                         while (o != null){
577                                 if (o.getName() != null)
578                                         name = o.getName()+"."+name;
579                                 prev = o;
580                                 o = o.getParent();
581                         }
582                         name = name.substring(0, name.length()-1);
583                         switch (prev.getType()) {
584                         case COMPLEX_TYPE:
585                                 return ontRoot+getComplexTypePrefix()+rel+name;
586                         case ELEMENT:
587                                 return ontRoot+rel+name;
588                         case ATTRIBUTE_GROUP:
589                                 return ontRoot+getAttributeGroupPrefix()+rel+name;
590                         case SIMPLE_TYPE:
591                                 return ontRoot+getSimpleTypePrefix()+rel+name;
592                         }
593                 }
594                 throw new RuntimeException();
595                 
596         }
597         
598         
599 }