1 package org.simantics.xml.sax;
3 import java.io.FileNotFoundException;
4 import java.io.PrintWriter;
5 import java.io.StringWriter;
6 import java.util.ArrayDeque;
7 import java.util.Deque;
8 import java.util.HashSet;
9 import java.util.LinkedHashSet;
10 import java.util.List;
13 import javax.xml.namespace.QName;
15 import org.simantics.utils.datastructures.BijectionMap;
16 import org.simantics.xml.sax.SchemaConversionBase.Inheritance;
17 import org.simantics.xml.sax.SchemaConversionBase.RefType;
18 import org.simantics.xml.sax.SchemaObject.ObjectType;
19 import org.simantics.xml.sax.configuration.AttributeComposition;
20 import org.simantics.xml.sax.configuration.IDReference;
21 import org.w3._2001.xmlschema.Annotated;
22 import org.w3._2001.xmlschema.Attribute;
23 import org.w3._2001.xmlschema.AttributeGroup;
24 import org.w3._2001.xmlschema.Element;
25 import org.w3._2001.xmlschema.LocalComplexType;
26 import org.w3._2001.xmlschema.LocalSimpleType;
27 import org.w3._2001.xmlschema.NamedAttributeGroup;
28 import org.w3._2001.xmlschema.NamedGroup;
29 import org.w3._2001.xmlschema.Schema;
30 import org.w3._2001.xmlschema.SimpleType;
32 //public class OntologyGenerator extends SchemaConversionBase {
33 public class OntologyGenerator implements SchemaConversionComponent {
34 SchemaConversionBase base;
36 public OntologyGenerator(SchemaConverter converter, SchemaConversionBase base) {
38 this.converter = converter;
39 this.schema = base.schema;
40 this.ontologyUri = base.ontologyURI;
41 this.className = base.className;
44 String ontRoot = "ONT.";
45 String commentTag = "//";
51 SchemaConverter converter;
53 PrintWriter writer = null;
55 public void createOntology() throws FileNotFoundException {
56 StringWriter stringWriter = null;
57 if (converter.getOntologyFile() == null) {
58 stringWriter = new StringWriter();
59 writer = new PrintWriter(stringWriter);
61 writer = new PrintWriter(converter.getOntologyFile());
68 if (stringWriter != null)
69 System.out.println(stringWriter.toString());
72 protected void handle() {
73 ontRoot = converter.shortName;
75 for (String s : converter.getHeader()) {
76 writer.println(commentTag + " " + s);
79 writer.println("L0 = <http://www.simantics.org/Layer0-1.1>");
80 writer.println("XML = <http://www.simantics.org/XML-1.0>");
82 if (converter.isPrimary()) {
83 writer.println(ontRoot + " = <" + ontologyUri +"> : L0.Ontology");
84 writer.println(" @L0.new");
85 writer.println(" L0.HasResourceClass \"" + className +"\"");
87 writer.println(ontRoot + " = <" + ontologyUri +">");
92 Set<SchemaConverter> children = new HashSet<>();
93 Deque<SchemaConverter> stack = new ArrayDeque<>();
94 stack.addAll(converter.getSubConverters());
95 while (!stack.isEmpty()) {
96 SchemaConverter sc = stack.pop();
97 if (children.contains(sc))
100 stack.addAll(sc.getSubConverters());
102 children.remove(converter);
103 for (SchemaConverter sc : children) {
104 writer.println(sc.shortName + " = <" + sc.ontologyUri +">");
110 writer.println(ontRoot+"SimpleTypes : L0.Library");
111 writer.println(ontRoot+"ComplexTypes : L0.Library");
112 writer.println(ontRoot+"AttributeGroups : L0.Library");
114 writer.println(commentTag + " Interpreted from schema");
122 protected String getType(QName qtype, String rel) {
123 String ontType = base.getL0TypeFromPrimitiveType(qtype);
127 if (base.isComplexTypeRef(qtype.getLocalPart()))
128 return getName(base.getComplexType(qtype), rel);
129 else if (base.isSimpleTypeRef(qtype.getLocalPart()))
130 return getName(base.getSimpleType(qtype), rel);
131 else if (base.isElementRef(qtype.getLocalPart()))
132 return getName(base.getElement(qtype), rel);
134 throw new RuntimeException("Reference to unknown type " + qtype.getLocalPart());
137 public String getSimpleTypePrefix() {
138 return "SimpleTypes.";
141 public String getComplexTypePrefix() {
142 return "ComplexTypes.";
145 public String getAttributeGroupPrefix() {
146 return "AttributeGroups.";
149 public String handleChoice(SchemaObject parent, SchemaElement indicator, java.util.List<SchemaElement> elements, String name) {
150 boolean single = true;
151 for (SchemaElement e : elements) {
152 if (e.getRestriction().many()) {
157 String relationName = getName(parent)+".has"+name;
158 writer.print(relationName);
159 writer.print(" <R XML.hasElement");
163 String elementListType = getName(parent) + "." + name + "_List";
164 writer.println(elementListType + " <T XML.ElementList");
165 writer.println(relationName + "_List <R XML.hasElementList : L0.FunctionalRelation");
166 writer.println(" --> " + elementListType);
175 public void handleIndicator(SchemaObject parent, SchemaElement indicator, SchemaElement element, String refName, RefType refType, String baseRelationName) {
176 if (refType != RefType.Element) {
177 QName referenceType = null;
178 if (refType == RefType.Type) {
179 referenceType = element.getElement().getType();
180 //refName = element.getElement().getName()
181 SchemaObject eObj = base.getElement(element.getElement());//base.elements.get(element.getElement());
183 refName = eObj.getName();
185 referenceType = element.getElement().getRef();
187 refName = base.getName(referenceType);
189 String type = base.getL0TypeFromPrimitiveType(referenceType);
190 SchemaObject obj = null;
192 obj = base.getWithName(referenceType);
193 writer.print(getName(parent)+".has"+refName + " <R XML.hasElement <R " + getName(obj,"has"));
194 if (baseRelationName != null) writer.print(" <R " + baseRelationName);
197 writer.print(getName(parent)+".has"+refName + " <R XML.hasElement");
198 if (baseRelationName != null) writer.print(" <R " + baseRelationName);
200 writer.println(" --> " + getType(referenceType, ""));
203 if (base.useElementList(parent, indicator,element, refType == RefType.Reference, refName, referenceType)) {
206 writer.println(getName(parent)+"."+refName + "List <T XML.ElementList");
207 writer.println(getName(parent)+".has"+refName + "_List <R " + getName(obj,"has")+"_List : L0.FunctionalRelation");
209 writer.println(getName(parent)+"."+refName + "_List <T XML.ElementList");
210 writer.println(getName(parent)+".has"+refName + "_List <R XML.hasElementList : L0.FunctionalRelation");
214 Element attrs = element.getElement();
215 SchemaObject obj = base.getWithObj(parent, attrs);
217 refName = obj.getName();
219 writer.print(getName(parent)+".has"+refName + " <R " + getName(obj,"has"));
220 if (baseRelationName != null) writer.print(" <R " + baseRelationName);
222 writer.println(" --> " + getName(obj));
223 if (base.useElementList(parent, indicator,element, false, refName, new QName(obj.getName()))) {
224 writer.println(getName(parent)+"."+refName + "_List <T XML.ElementList");
225 writer.println(getName(parent)+".has"+refName + "_List <R " + getName(obj,"has")+"_List : L0.FunctionalRelation");
232 public void handleIndicator(SchemaObject parent, SchemaElement indicator, SchemaElement any) {
237 public void handle(SchemaObject parent, NamedGroup attribute) {
238 // TODO Auto-generated method stub
243 public void handle(SchemaObject parent, Attribute attribute) {
244 String name = base.getName(attribute);
245 QName primitiveType = attribute.getType();
246 LocalSimpleType simpleType = attribute.getSimpleType();
247 QName ref = attribute.getRef();
252 relationName = ontRoot+"has"+name;
254 relationName = getName(parent)+".has"+name;
255 relationType = "XML.hasAttribute";
257 else if (ref != null && parent != null) {
258 relationName = getName(parent)+".has"+base.getName(ref);
259 relationType = converter.getShortName(ref.getNamespaceURI())+".has"+base.getName(ref);
261 throw new RuntimeException();
264 String ontType = null;
265 if (primitiveType != null) {
266 ontType = base.getL0TypeFromPrimitiveType(primitiveType);
267 if (ontType != null) {
268 id = base.getTypeEntry(primitiveType).id;
270 relationType = "XML.hasID";
274 } else if (simpleType != null){
275 // Restriction restriction = simpleType.getRestriction();
276 // if (restriction == null || simpleType.getUnion() != null || simpleType.getName() != null || simpleType.getId() != null)
277 // throw new RuntimeException();
278 // QName base = restriction.getBase();
279 QName base = this.base.getSimpleTypeBase(simpleType);
282 ontType = this.base.getL0TypeFromPrimitiveType(base);
284 // for (Object facetWrap : restriction.getFacets()) {
285 // JAXBElement<?> element = (JAXBElement<?>)facetWrap;
286 // QName elementName = element.getName();
287 // Facet facet = (Facet)element.getValue();
293 writer.println(relationName+ " <R " + relationType + ": L0.FunctionalRelation");
295 // no need to add range restriction
296 } else if (ontType != null) {
297 writer.println(" --> " + ontType);
298 } else if (primitiveType != null) {
299 writer.println(" <R " + getType(primitiveType, "has"));
304 public void handleAttributes(SchemaObject simpleTypeObj) {
305 // SchemaObject parent = simpleTypeObj.getParent();
306 // SimpleType simpleType = simpleTypeObj.getSimpleType();
307 // Restriction restriction = simpleType.getRestriction();
308 // QName base = restriction.getBase();
309 // String ontType = getL0TypeFromPrimitiveType(base);
313 public void handle(SchemaObject parent, AttributeGroup attributeGroup) {
314 if (parent == null) {
315 NamedAttributeGroup group = (NamedAttributeGroup)attributeGroup;
316 writer.println(ontRoot+getAttributeGroupPrefix()+group.getName()+ " <T XML.AttributeGroup");
317 SchemaObject obj = new SchemaObject(base,parent,attributeGroup);
318 for (Annotated annotated : group.getAttributeOrAttributeGroup()) {
319 if (annotated instanceof Attribute) {
320 //handle(getAttributeGroupPrefix()+group.getName(),(Attribute)annotated);
321 handle(obj,(Attribute)annotated);
322 } else if (annotated instanceof AttributeGroup) {
323 handle(obj,(AttributeGroup)annotated);
324 //throw new RuntimeException("Cannot handle nested attribute groups");
328 writer.println(getName(parent) +" L0.Inherits " + ontRoot + getAttributeGroupPrefix() + base.getName(attributeGroup.getRef()));
334 public void handleAttributeComposition(SchemaObject parent, AttributeComposition composition, BijectionMap<org.simantics.xml.sax.configuration.Attribute, Annotated> attributes) {
335 Attribute compositionAttribute = new Attribute();
336 compositionAttribute.setName(composition.getName());
337 QName type = new QName(SchemaConversionBase.CONVERSION_NS, composition.getType());
338 compositionAttribute.setType(type);
339 handle(parent, compositionAttribute);
343 public void handleSimpleType(SchemaObject parent, SchemaObject simpleTypeObj) {
344 SimpleType simpleType = simpleTypeObj.getSimpleType();
345 String name = simpleType.getName();
347 org.w3._2001.xmlschema.List list = simpleType.getList();
349 // TODO : process restriction in lists
350 String relationName = getName(simpleTypeObj, "has");
351 writer.println(relationName+ " <R XML.hasAttribute : L0.FunctionalRelation");
353 String ontType = base.getL0Type(new QName(SchemaConversionBase.SCHEMA_NS, "string"));
354 writer.println(" --> " + ontType);
356 QName base = this.base.getSimpleTypeBase(simpleType);
357 writer.println(getName(simpleTypeObj) + " <T " + getType(base, ""));
359 String relationName = getName(simpleTypeObj, "has");
361 writer.println(relationName+ " : L0.FunctionalRelation");
362 writer.println(" --> " + getName(simpleTypeObj));
364 // Restriction restriction = simpleType.getRestriction();
365 // if (restriction != null) {
367 // QName base = restriction.getBase();
368 // String ontType = getL0Type(base);
369 // writer.println(" --> " + ontType);
370 // } else if (simpleType.getId() != null) {
371 // throw new RuntimeException(simpleType.getName() + " restriction error");
372 // } else if (simpleType.getUnion() != null) {
373 // Union union = simpleType.getUnion();
374 // String ontType = null;
375 // if (union.getMemberTypes().size() > 0) {
376 // for (QName type : union.getMemberTypes()) {
377 // String sType = null;
378 // TypeEntry entry = getTypeEntry(type);
379 // if (entry == null) {
380 // SchemaObject obj = simpleTypeName.get(type.getLocalPart());
381 // Inheritance inheritance = new Inheritance("");
382 // getAtomicTypeInheritance(type, obj, inheritance);
383 // sType = inheritance.atomicType.l0Type;
385 // sType = entry.l0Type;
387 // if (ontType == null)
389 // else if (!ontType.equals(sType))
390 // throw new RuntimeException(simpleType.getName() + " union has incompatible member types");
393 // if (union.getSimpleType().size() == 0)
394 // throw new RuntimeException(simpleType.getName() + " union error");
395 // for (SimpleType s : union.getSimpleType()) {
396 // if (restriction == null)
397 // restriction = s.getRestriction();
399 // Restriction r = s.getRestriction();
400 // if (!r.getBase().equals(restriction.getBase()))
401 // throw new RuntimeException(simpleType.getName() + " union has incompatible restriction bases");
404 // QName base = restriction.getBase();
405 // ontType = getL0Type(base);
407 // writer.println(" --> " + ontType);
409 // throw new RuntimeException(simpleType.getName() + " restriction error");
416 public void handleComplexType(SchemaObject topLevelComplexType) {
417 String name = getName(topLevelComplexType);
418 // if (topLevelComplexType.getName().equals("Reference"))
419 // System.out.println();
421 // String baseType = "XML.ComplexType";
423 // QName base = getComplexTypeBase(topLevelComplexType.getComplexType());
424 // if (base != null) {
425 // baseType = getType(base);
427 // base = getSimpleTypeBase(topLevelComplexType.getSimpleType());
428 // if (base != null) {
429 // baseType = getType(base);
431 Inheritance inheritance = base.getInheritance(topLevelComplexType);
433 // writer.println(name+ " <T "+baseType);
436 if (inheritance.additionalClass != null) {
437 writer.println(name+ " <T " + inheritance.baseClass + " <T " + inheritance.additionalClass);
438 } else if (inheritance.atomicType != null){
439 writer.println(name+ " <T " + inheritance.baseClass + " <T " + inheritance.atomicType.l0Type);
441 writer.println(name+ " <T " + inheritance.baseClass);
443 writer.println(name + "_List <T XML.ElementList");
446 String relationName = getName(topLevelComplexType,"has");
447 writer.println(relationName+ " <R XML.hasComplexType");
448 writer.println(" --> " + name);
449 writer.println(relationName+ "_List <R XML.hasElementList");
450 writer.println(" --> " + name + "_List");
454 // if (!baseType.equals(inheritance.baseClass))
455 // System.out.println();
456 //super.handleComplexType(topLevelComplexType);
457 base.handleComplexTypeAttributes(topLevelComplexType);
458 base.handleComplexTypeExtension(topLevelComplexType);
459 base.handleExtensionAttributes(topLevelComplexType);
464 public void handleElement(SchemaObject elementObj) {
465 Element element = elementObj.getElement();
466 String name = getName(elementObj);//element.getName();
468 if (name.contains("Canvas"))
469 System.out.println();
471 String type = "XML.Element";
472 Set<String> types = new LinkedHashSet<String>();
473 if (element.getType() != null) {
474 types.add(getType(element.getType(), ""));
476 QName base = this.base.getElementBase(element);
478 if (base.getNamespaceURI().equals(SchemaConversionBase.SCHEMA_NS)) {
479 String l0Type = this.base.getL0Type(base);
481 throw new RuntimeException("Cannot get L0 type for " + base.getLocalPart());
483 } else if (this.base.isElementRef(base.getLocalPart()))
484 types.add(ontRoot+this.base.getName(base));
486 types.add(ontRoot+getComplexTypePrefix()+this.base.getName(base));
488 QName substitution = element.getSubstitutionGroup();
489 if (substitution != null) {
490 if (this.base.isElementRef(substitution.getLocalPart()))
491 types.add(ontRoot+this.base.getName(substitution));
493 types.add( ontRoot+getComplexTypePrefix()+this.base.getName(substitution));
495 for (String t : types) {
499 String relationName = getName(elementObj,"has");//ontRoot+"has"+name;
500 // if (elementObj.getParent() != null) {
501 // //relationName = ontRoot+getComplexTypePrefix()+"has"+name.substring(getComplexTypePrefix().length());
502 // relationName = ontRoot+getName(elementObj.getParent()) + "has"+element.getName();
504 writer.println(relationName+ " <R XML.hasElement");
505 writer.println(relationName+ "_List <R XML.hasElementList");
507 writer.println(name+ " <T "+type);
509 LocalComplexType complexType = element.getComplexType();
510 LocalSimpleType simpleType = element.getSimpleType();
512 if (complexType != null) {
513 SchemaObject complexTypeObj = this.base.getComplexType(complexType);
514 this.base.handleElementComplexTypeAttributes(complexTypeObj);
515 this.base.handleComplexTypeExtension(complexTypeObj);
516 } else if (simpleType != null) {
517 SchemaObject simpleTypeObj = this.base.getSimpleType(simpleType);
518 this.base.handleElementSimpleTypeAttributes(simpleTypeObj);
521 List<IDReference> references = this.base.getIDReferences(element);
523 for (IDReference ref : references) {
524 writer.println(name+"."+ref.getReference().getName()+ " <R XML.hasReference");
531 public String getBaseClass(ObjectType type) {
532 if (type == ObjectType.ELEMENT)
533 return "XML.Element";
534 if (type == ObjectType.COMPLEX_TYPE)
535 return "XML.ComplexType";
536 throw new RuntimeException("ObjectType " + type + " has no base class");
541 public String getName(SchemaObject obj) {
542 if (obj.getParent() == null) {
543 switch (obj.getType()) {
545 //return ontRoot+getComplexTypePrefix()+obj.getName();
546 return obj.getLibShortName()+"."+getComplexTypePrefix()+obj.getName();
548 //return ontRoot+obj.getName();
549 return obj.getLibShortName()+"."+obj.getName();
550 case ATTRIBUTE_GROUP:
551 //return ontRoot+getAttributeGroupPrefix()+obj.getName();
552 return obj.getLibShortName()+"."+getAttributeGroupPrefix()+obj.getName();
554 //return ontRoot+getSimpleTypePrefix()+obj.getName();
555 return obj.getLibShortName()+"."+getSimpleTypePrefix()+obj.getName();
558 SchemaObject o = obj;
559 SchemaObject prev = null;
562 if (o.getName() != null)
563 name = o.getName()+"."+name;
567 name = name.substring(0, name.length()-1);
568 switch (prev.getType()) {
570 //return ontRoot+getComplexTypePrefix()+name;
571 return obj.getLibShortName()+"."+getComplexTypePrefix()+name;
573 //return ontRoot+name;
574 return obj.getLibShortName()+"."+name;
575 case ATTRIBUTE_GROUP:
576 //return ontRoot+getAttributeGroupPrefix()+name;
577 return obj.getLibShortName()+"."+getAttributeGroupPrefix()+name;
579 //return ontRoot+getSimpleTypePrefix()+name;
580 return obj.getLibShortName()+"."+getSimpleTypePrefix()+name;
583 throw new RuntimeException();
587 public String getName(SchemaObject parent, SchemaElement e, String rel) {
588 QName ref = e.getElement().getRef();
590 return converter.getShortName(ref.getNamespaceURI()) + rel + base.getName(ref);
593 return getName(parent, "") + "." + rel + e.getElement().getName();
597 public String getName(SchemaObject obj, String rel) {
598 if (obj.getParent() == null) {
599 switch (obj.getType()) {
601 return obj.getLibShortName()+"."+getComplexTypePrefix()+rel+obj.getName();
603 return obj.getLibShortName()+"."+rel+obj.getName();
604 case ATTRIBUTE_GROUP:
605 return obj.getLibShortName()+"."+getAttributeGroupPrefix()+rel+obj.getName();
607 return obj.getLibShortName()+"."+getSimpleTypePrefix()+rel+obj.getName();
609 return obj.getLibShortName()+"."+rel+obj.getName();
612 SchemaObject o = obj;
613 SchemaObject prev = null;
616 if (o.getName() != null)
617 name = o.getName()+"."+name;
621 name = name.substring(0, name.length()-1);
622 switch (prev.getType()) {
624 return obj.getLibShortName()+"."+getComplexTypePrefix()+rel+name;
626 return obj.getLibShortName()+"."+rel+name;
627 case ATTRIBUTE_GROUP:
628 return obj.getLibShortName()+"."+getAttributeGroupPrefix()+rel+name;
630 return obj.getLibShortName()+"."+getSimpleTypePrefix()+rel+name;
632 return obj.getLibShortName()+"."+rel+obj.getName();
635 throw new RuntimeException();