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.ArrayList;
7 import java.util.LinkedHashSet;
11 import javax.xml.namespace.QName;
13 import org.simantics.utils.datastructures.BijectionMap;
14 import org.simantics.xml.sax.SchemaConversionBase.Inheritance;
15 import org.simantics.xml.sax.SchemaConversionBase.InheritanceType;
16 import org.simantics.xml.sax.SchemaConversionBase.RefType;
17 import org.simantics.xml.sax.SchemaObject.ObjectType;
18 import org.simantics.xml.sax.configuration.AttributeComposition;
19 import org.simantics.xml.sax.configuration.IDReference;
20 import org.w3._2001.xmlschema.Annotated;
21 import org.w3._2001.xmlschema.Attribute;
22 import org.w3._2001.xmlschema.AttributeGroup;
23 import org.w3._2001.xmlschema.Element;
24 import org.w3._2001.xmlschema.LocalComplexType;
25 import org.w3._2001.xmlschema.LocalSimpleType;
26 import org.w3._2001.xmlschema.NamedAttributeGroup;
27 import org.w3._2001.xmlschema.NamedGroup;
28 import org.w3._2001.xmlschema.Restriction;
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 +">");
93 writer.println(ontRoot+"ComplexTypes : L0.Library");
94 writer.println(ontRoot+"AttributeGroups : L0.Library");
96 writer.println(commentTag + " Interpreted from schema");
102 protected String getType(QName qtype) {
103 String ontType = base.getL0TypeFromPrimitiveType(qtype);
106 else if (base.isComplexTypeRef(qtype.getLocalPart()))
107 return ontRoot+getComplexTypePrefix()+qtype.getLocalPart();
108 else if (base.isSimpleTypeRef(qtype.getLocalPart()))
109 return ontRoot+qtype.getLocalPart();
110 else if (base.isElementRef(qtype.getLocalPart()))
111 return ontRoot+qtype.getLocalPart();
112 else if (qtype.getPrefix() != null && qtype.getPrefix().length() > 0) {
113 return ontRoot+qtype.getPrefix()+qtype.getLocalPart();
115 throw new RuntimeException("Reference to unknown type " + qtype.getLocalPart());
118 public String getComplexTypePrefix() {
119 return "ComplexTypes.";
122 public String getAttributeGroupPrefix() {
123 return "AttributeGroups.";
126 public void handleChoice(SchemaObject parent, SchemaElement indicator, java.util.List<SchemaElement> elements, String name) {
127 boolean single = true;
128 for (SchemaElement e : elements) {
129 if (e.getRestriction().many()) {
134 String relationName = getName(parent)+".has"+name;
135 writer.print(relationName);
137 List<String> types = new ArrayList<String>();
138 for (SchemaElement e : elements) {
139 Element localElement = e.getElement();
140 QName refType = null;
143 if (localElement.getName() != null) {
144 refType = localElement.getType();
145 type = base.getL0TypeFromPrimitiveType(refType);
146 } else if (localElement.getRef() != null) {
147 refType = localElement.getRef();
148 type = base.getL0TypeFromPrimitiveType(refType);
151 SchemaObject obj = base.getWithName(refType);
152 types.add(getName(obj,"has"));
155 if (types.size() > 0) {
156 for (String type : types) {
157 writer.print(" <R " + type);
160 writer.print(" <R XML.hasElement");
165 for (SchemaElement e : elements) {
166 Element localElement = e.getElement();
167 QName refType = null;
169 if (localElement.getName() != null) {
170 refType = localElement.getType();
171 type = getType(refType);
172 } else if (localElement.getRef() != null) {
173 refType = localElement.getRef();
174 type = getType(refType);
177 writer.println(" --> " + type);
181 writer.println(ontRoot+name+ "List <T XML.ElementList");
182 if (types.size() == 0) {
183 writer.println(relationName+ "List <R XML.hasElementList : L0.FunctionalRelation");
185 writer.print(relationName+ "List");
186 for (String type : types) {
187 writer.print(" <R " + type+"List");
189 writer.println(" : L0.FunctionalRelation");
191 writer.println(" --> " + ontRoot+name+"List");
198 public void handleIndicator(SchemaObject parent, SchemaElement indicator, SchemaElement element, String refName, RefType refType) {
199 if (refType != refType.Element) {
200 QName referenceType = null;
201 if (refType == RefType.Type) {
202 referenceType = element.getElement().getType();
203 //refName = element.getElement().getName()
204 SchemaObject eObj = base.getElement(element.getElement());//base.elements.get(element.getElement());
206 refName = eObj.getName();
208 referenceType = element.getElement().getRef();
210 refName = referenceType.getLocalPart();
212 String type = base.getL0TypeFromPrimitiveType(referenceType);
213 SchemaObject obj = null;
215 obj = base.getWithName(referenceType);
217 writer.println(getName(parent)+".has"+refName + " <R " + getName(obj,"has"));
218 writer.println(" --> " + getName(obj));
220 writer.println(getName(parent)+".has"+refName + " <R XML.hasElement");
221 writer.println(" --> " + getType(referenceType));
224 if (base.useElementList(parent, indicator,element, refType == RefType.Reference, refName, referenceType)) {
227 writer.println(getName(parent)+"."+refName + "List <T XML.ElementList");
228 writer.println(getName(parent)+".has"+refName + "List <R " + getName(obj,"has")+"List : L0.FunctionalRelation");
230 writer.println(getName(parent)+"."+refName + "List <T XML.ElementList");
231 writer.println(getName(parent)+".has"+refName + "List <R XML.hasElementList : L0.FunctionalRelation");
235 Element attrs = element.getElement();
236 SchemaObject obj = base.getWithObj(parent, attrs);
238 refName = obj.getName();
240 writer.println(getName(parent)+".has"+refName + " <R " + getName(obj,"has"));
241 writer.println(" --> " + getName(obj));
242 if (base.useElementList(parent, indicator,element, false, refName, new QName(obj.getName()))) {
243 writer.println(getName(parent)+"."+refName + "List <T XML.ElementList");
244 writer.println(getName(parent)+".has"+refName + "List <R " + getName(obj,"has")+"List : L0.FunctionalRelation");
251 public void handleIndicator(SchemaObject parent, SchemaElement indicator, SchemaElement any) {
256 public void handle(SchemaObject parent, NamedGroup attribute) {
257 // TODO Auto-generated method stub
262 public void handle(SchemaObject parent, Attribute attribute) {
263 String name = attribute.getName();
264 QName primitiveType = attribute.getType();
265 LocalSimpleType simpleType = attribute.getSimpleType();
266 QName ref = attribute.getRef();
271 relationName = ontRoot+"has"+name;
273 relationName = getName(parent)+".has"+name;
274 relationType = "XML.hasAttribute";
276 else if (ref != null && parent != null) {
277 relationName = getName(parent)+".has"+ref.getLocalPart();
278 relationType = ontRoot+"has"+ref.getLocalPart();
280 throw new RuntimeException();
283 String ontType = null;
284 if (primitiveType != null) {
285 ontType = base.getL0TypeFromPrimitiveType(primitiveType);
286 if (ontType != null) {
287 id = base.getTypeEntry(primitiveType).id;
289 relationType = "XML.hasID";
293 } else if (simpleType != null){
294 // Restriction restriction = simpleType.getRestriction();
295 // if (restriction == null || simpleType.getUnion() != null || simpleType.getName() != null || simpleType.getId() != null)
296 // throw new RuntimeException();
297 // QName base = restriction.getBase();
298 QName base = this.base.getSimpleTypeBase(simpleType);
301 ontType = this.base.getL0TypeFromPrimitiveType(base);
303 // for (Object facetWrap : restriction.getFacets()) {
304 // JAXBElement<?> element = (JAXBElement<?>)facetWrap;
305 // QName elementName = element.getName();
306 // Facet facet = (Facet)element.getValue();
312 writer.println(relationName+ " <R " + relationType + ": L0.FunctionalRelation");
314 // no need to add range restriction
315 } else if (ontType != null) {
316 writer.println(" --> " + ontType);
317 } else if (primitiveType != null) {
318 writer.println(" <R "+ontRoot+"has"+primitiveType.getLocalPart());
323 public void handleAttributes(SchemaObject simpleTypeObj) {
324 // SchemaObject parent = simpleTypeObj.getParent();
325 // SimpleType simpleType = simpleTypeObj.getSimpleType();
326 // Restriction restriction = simpleType.getRestriction();
327 // QName base = restriction.getBase();
328 // String ontType = getL0TypeFromPrimitiveType(base);
332 public void handle(SchemaObject parent, AttributeGroup attributeGroup) {
333 if (parent == null) {
334 NamedAttributeGroup group = (NamedAttributeGroup)attributeGroup;
335 writer.println(ontRoot+getAttributeGroupPrefix()+group.getName()+ " <T XML.AttributeGroup");
336 SchemaObject obj = new SchemaObject(parent,attributeGroup);
337 for (Annotated annotated : group.getAttributeOrAttributeGroup()) {
338 if (annotated instanceof Attribute) {
339 //handle(getAttributeGroupPrefix()+group.getName(),(Attribute)annotated);
340 handle(obj,(Attribute)annotated);
341 } else if (annotated instanceof AttributeGroup) {
342 handle(obj,(AttributeGroup)annotated);
343 //throw new RuntimeException("Cannot handle nested attribute groups");
347 writer.println(getName(parent) +" L0.Inherits " + ontRoot + getAttributeGroupPrefix() + attributeGroup.getRef().getLocalPart());
353 public void handleAttributeComposition(SchemaObject parent, AttributeComposition composition, BijectionMap<org.simantics.xml.sax.configuration.Attribute, Annotated> attributes) {
354 Attribute compositionAttribute = new Attribute();
355 compositionAttribute.setName(composition.getName());
356 QName type = new QName(SchemaConversionBase.CONVERSION_NS, composition.getType());
357 compositionAttribute.setType(type);
358 handle(parent, compositionAttribute);
362 public void handleSimpleType(SchemaObject parent, SchemaObject simpleTypeObj) {
363 SimpleType simpleType = simpleTypeObj.getSimpleType();
364 String name = simpleType.getName();
366 org.w3._2001.xmlschema.List list = simpleType.getList();
368 // TODO : process restriction in lists
369 String relationName = ontRoot+"has"+name;
371 relationName = getName(parent)+".has"+name;
372 writer.println(relationName+ " <R XML.hasAttribute : L0.FunctionalRelation");
374 String ontType = base.getL0Type(new QName(SchemaConversionBase.SCHEMA_NS, "string"));
375 writer.println(" --> " + ontType);
377 String relationName = ontRoot+"has"+name;
379 relationName = getName(parent)+".has"+name;
381 writer.println(relationName+ " <R XML.hasAttribute : L0.FunctionalRelation");
383 QName base = this.base.getSimpleTypeBase(simpleType);
384 Inheritance inheritance = new Inheritance("");
385 this.base.getAtomicTypeInheritance(base, inheritance);
386 if (inheritance.atomicType == null)
387 throw new RuntimeException("Could not locate atomic type for SimpleType " + simpleType.getName());
388 writer.println(" --> " + inheritance.atomicType.l0Type);
390 // Restriction restriction = simpleType.getRestriction();
391 // if (restriction != null) {
393 // QName base = restriction.getBase();
394 // String ontType = getL0Type(base);
395 // writer.println(" --> " + ontType);
396 // } else if (simpleType.getId() != null) {
397 // throw new RuntimeException(simpleType.getName() + " restriction error");
398 // } else if (simpleType.getUnion() != null) {
399 // Union union = simpleType.getUnion();
400 // String ontType = null;
401 // if (union.getMemberTypes().size() > 0) {
402 // for (QName type : union.getMemberTypes()) {
403 // String sType = null;
404 // TypeEntry entry = getTypeEntry(type);
405 // if (entry == null) {
406 // SchemaObject obj = simpleTypeName.get(type.getLocalPart());
407 // Inheritance inheritance = new Inheritance("");
408 // getAtomicTypeInheritance(type, obj, inheritance);
409 // sType = inheritance.atomicType.l0Type;
411 // sType = entry.l0Type;
413 // if (ontType == null)
415 // else if (!ontType.equals(sType))
416 // throw new RuntimeException(simpleType.getName() + " union has incompatible member types");
419 // if (union.getSimpleType().size() == 0)
420 // throw new RuntimeException(simpleType.getName() + " union error");
421 // for (SimpleType s : union.getSimpleType()) {
422 // if (restriction == null)
423 // restriction = s.getRestriction();
425 // Restriction r = s.getRestriction();
426 // if (!r.getBase().equals(restriction.getBase()))
427 // throw new RuntimeException(simpleType.getName() + " union has incompatible restriction bases");
430 // QName base = restriction.getBase();
431 // ontType = getL0Type(base);
433 // writer.println(" --> " + ontType);
435 // throw new RuntimeException(simpleType.getName() + " restriction error");
442 public void handleComplexType(SchemaObject topLevelComplexType) {
443 String name = getName(topLevelComplexType);
444 // if (topLevelComplexType.getName().equals("Reference"))
445 // System.out.println();
447 String relationName = getName(topLevelComplexType,"has");//ontRoot+"has"+name;
449 writer.println(relationName+ " <R XML.hasComplexType");
450 writer.println(relationName+ "List <R XML.hasElementList");
451 //writer.println(" --> " + ontRoot+getComplexTypePrefix()+name);
452 writer.println(" --> " + name);
454 // String baseType = "XML.ComplexType";
456 // QName base = getComplexTypeBase(topLevelComplexType.getComplexType());
457 // if (base != null) {
458 // baseType = getType(base);
460 // base = getSimpleTypeBase(topLevelComplexType.getSimpleType());
461 // if (base != null) {
462 // baseType = getType(base);
464 Inheritance inheritance = base.getInheritance(topLevelComplexType);
466 // writer.println(name+ " <T "+baseType);
468 if(inheritance.type == InheritanceType.AtomicType) {
469 writer.println(name+ " <T "+inheritance.baseClass + " <T "+inheritance.atomicType.l0Type);
471 writer.println(name+ " <T "+inheritance.baseClass);
473 // if (!baseType.equals(inheritance.baseClass))
474 // System.out.println();
475 //super.handleComplexType(topLevelComplexType);
476 base.handleComplexTypeAttributes(topLevelComplexType);
477 base.handleComplexTypeExtension(topLevelComplexType);
478 base.handleExtensionAttributes(topLevelComplexType);
483 public void handleElement(SchemaObject elementObj) {
484 Element element = elementObj.getElement();
485 String name = getName(elementObj);//element.getName();
487 if ("Text".equals(name))
488 System.out.println();
490 String type = "XML.Element";
491 Set<String> types = new LinkedHashSet<String>();
492 if (element.getType() != null) {
493 types.add(getType(element.getType()));
495 QName base = this.base.getElementBase(element);
497 if (base.getNamespaceURI().equals(SchemaConversionBase.SCHEMA_NS)) {
498 String l0Type = this.base.getL0Type(base);
500 throw new RuntimeException("Cannot get L0 type for " + base.getLocalPart());
502 } else if (this.base.isElementRef(base.getLocalPart()))
503 types.add(ontRoot+base.getLocalPart());
505 types.add(ontRoot+getComplexTypePrefix()+base.getLocalPart());
507 QName substitution = element.getSubstitutionGroup();
508 if (substitution != null) {
509 if (this.base.isElementRef(substitution.getLocalPart()))
510 types.add(ontRoot+substitution.getLocalPart());
512 types.add( ontRoot+getComplexTypePrefix()+substitution.getLocalPart());
514 for (String t : types) {
518 String relationName = getName(elementObj,"has");//ontRoot+"has"+name;
519 // if (elementObj.getParent() != null) {
520 // //relationName = ontRoot+getComplexTypePrefix()+"has"+name.substring(getComplexTypePrefix().length());
521 // relationName = ontRoot+getName(elementObj.getParent()) + "has"+element.getName();
523 writer.println(relationName+ " <R XML.hasElement");
524 writer.println(relationName+ "List <R XML.hasElementList");
526 writer.println(name+ " <T "+type);
528 LocalComplexType complexType = element.getComplexType();
529 LocalSimpleType simpleType = element.getSimpleType();
531 if (complexType != null) {
532 SchemaObject complexTypeObj = this.base.getComplexType(complexType);
533 this.base.handleElementComplexTypeAttributes(complexTypeObj);
534 this.base.handleComplexTypeExtension(complexTypeObj);
535 } else if (simpleType != null) {
536 SchemaObject simpleTypeObj = this.base.getSimpleType(simpleType);
537 this.base.handleElementSimpleTypeAttributes(simpleTypeObj);
540 List<IDReference> references = this.base.getIDReferences(element);
542 for (IDReference ref : references) {
543 writer.println(name+"."+ref.getReference().getName()+ " <R XML.hasReference");
550 public String getBaseClass(ObjectType type) {
551 if (type == ObjectType.ELEMENT)
552 return "XML.Element";
553 if (type == ObjectType.COMPLEX_TYPE)
554 return "XML.ComplexType";
555 throw new RuntimeException("ObjectType " + type + " has no base class");
559 public String getName(SchemaObject obj) {
560 if (obj.getParent() == null) {
561 switch (obj.getType()) {
563 return ontRoot+getComplexTypePrefix()+obj.getName();
565 return ontRoot+obj.getName();
566 case ATTRIBUTE_GROUP:
567 return ontRoot+getAttributeGroupPrefix()+obj.getName();
569 return ontRoot+obj.getName();
572 SchemaObject o = obj;
573 SchemaObject prev = null;
576 if (o.getName() != null)
577 name = o.getName()+"."+name;
581 name = name.substring(0, name.length()-1);
582 switch (prev.getType()) {
584 return ontRoot+getComplexTypePrefix()+name;
587 case ATTRIBUTE_GROUP:
588 return ontRoot+getAttributeGroupPrefix()+name;
593 throw new RuntimeException();
597 public String getName(SchemaObject obj, String rel) {
598 if (obj.getParent() == null) {
599 switch (obj.getType()) {
601 return ontRoot+getComplexTypePrefix()+rel+obj.getName();
603 return ontRoot+rel+obj.getName();
604 case ATTRIBUTE_GROUP:
605 return ontRoot+getAttributeGroupPrefix()+rel+obj.getName();
607 return ontRoot+rel+obj.getName();
610 SchemaObject o = obj;
611 SchemaObject prev = null;
614 if (o.getName() != null)
615 name = o.getName()+"."+name;
619 name = name.substring(0, name.length()-1);
620 switch (prev.getType()) {
622 return ontRoot+getComplexTypePrefix()+rel+name;
624 return ontRoot+rel+name;
625 case ATTRIBUTE_GROUP:
626 return ontRoot+getAttributeGroupPrefix()+rel+name;
628 return ontRoot+rel+name;
631 throw new RuntimeException();