package org.simantics.xml.sax; import java.io.FileNotFoundException; import java.io.PrintWriter; import java.io.StringWriter; import java.util.ArrayList; import java.util.LinkedHashSet; import java.util.List; import java.util.Set; import javax.xml.namespace.QName; import org.simantics.utils.datastructures.BijectionMap; import org.simantics.xml.sax.configuration.AttributeComposition; import org.simantics.xml.sax.configuration.Configuration; import org.simantics.xml.sax.configuration.IDReference; import org.w3._2001.xmlschema.Annotated; import org.w3._2001.xmlschema.Attribute; import org.w3._2001.xmlschema.AttributeGroup; import org.w3._2001.xmlschema.Element; import org.w3._2001.xmlschema.LocalComplexType; import org.w3._2001.xmlschema.LocalSimpleType; import org.w3._2001.xmlschema.NamedAttributeGroup; import org.w3._2001.xmlschema.Restriction; import org.w3._2001.xmlschema.Schema; import org.w3._2001.xmlschema.SimpleType; import org.w3._2001.xmlschema.TopLevelAttribute; public class OntologyGenerator extends SchemaConversionBase { public OntologyGenerator(Configuration configuration) { super(configuration); } String ontRoot = "ONT."; String commentTag = "//"; Schema schema; String ontologyUri; String className; SchemaConverter converter; PrintWriter writer = null; public void createOntology(Schema schema, String ontologyName, String className, SchemaConverter converter) throws FileNotFoundException { this.schema = schema; this.converter = converter; this.ontologyUri = ontologyName; this.className = className; // for (OpenAttrs attrs : schema.getIncludeOrImportOrRedefine()) { // if (attrs instanceof Annotation) { // Annotation ann = (Annotation)attrs; // for (Object o : ann.getAppinfoOrDocumentation()) { // if (o instanceof Documentation) { // Documentation doc = (Documentation)o; // } else if (o instanceof Appinfo) { // Appinfo info = (Appinfo)o; // } // } // } // } StringWriter stringWriter = null; if (converter.getOntologyFile() == null) { stringWriter = new StringWriter(); writer = new PrintWriter(stringWriter); } else { writer = new PrintWriter(converter.getOntologyFile()); } handle(schema); writer.flush(); writer.close(); if (stringWriter != null) System.out.println(stringWriter.toString()); } protected void handle(Schema schema) { String parts[] = ontologyUri.split("/"); String name = parts[parts.length-1]; ontRoot = name.substring(0, Math.min(3, name.length())).toUpperCase(); for (String s : converter.getHeader()) { writer.println(commentTag + " " + s); } writer.println(); writer.println("L0 = "); writer.println("XML = "); writer.println(); writer.println(ontRoot + " = <" + ontologyUri +"> : L0.Ontology"); writer.println(" @L0.new"); writer.println(" L0.HasResourceClass \"" + className +"\""); writer.println(); writer.println(); ontRoot += "."; writer.println(ontRoot+"ComplexTypes : L0.Library"); writer.println(ontRoot+"AttributeGroups : L0.Library"); writer.println(); writer.println(commentTag + " Interpreted from schema"); writer.println(); super.handle(schema); } protected String getType(QName qtype) { String ontType = getL0TypeFromPrimitiveType(qtype); if (ontType != null) return ontType; else if (isComplexTypeRef(qtype.getLocalPart())) return ontRoot+getComplexTypePrefix()+qtype.getLocalPart(); else if (isSimpleTypeRef(qtype.getLocalPart())) return ontRoot+qtype.getLocalPart(); else if (isElementRef(qtype.getLocalPart())) return ontRoot+qtype.getLocalPart(); else if (qtype.getPrefix() != null && qtype.getPrefix().length() > 0) { return ontRoot+qtype.getPrefix()+qtype.getLocalPart(); } throw new RuntimeException("Reference to unknown type " + qtype.getLocalPart()); } @Override protected void handle(TopLevelAttribute topLevelAttribute) { super.handle(topLevelAttribute); writer.println(); } @Override protected void handleSimpleType(SchemaObject topLevelSimpleType) { super.handleSimpleType(topLevelSimpleType); writer.println(); } public static String getComplexTypePrefix() { return "ComplexTypes."; } public static String getAttributeGroupPrefix() { return "AttributeGroups."; } @Override protected void handle(SchemaObject parent, SchemaElement indicator, List elements) { if (indicator.getType() == SchemaElement.ElementType.SEQUENCE || (indicator.getType() == SchemaElement.ElementType.CHOICE && indicator.getRestriction().many())) { for (SchemaElement e : elements) { handle(parent, indicator, e); } } else if (indicator.getType() == SchemaElement.ElementType.CHOICE) { String name = getChoiceName(elements); boolean single = true; for (SchemaElement e : elements) { if (e.getRestriction().many()) { single = false; break; } } String relationName = ontRoot+getName(parent)+".has"+name; writer.print(relationName); List types = new ArrayList(); for (SchemaElement e : elements) { Element localElement = e.getElement(); QName refType = null; String type = null; if (localElement.getName() != null) { refType = localElement.getType(); type = getL0TypeFromPrimitiveType(refType); } else if (localElement.getRef() != null) { refType = localElement.getRef(); type = getL0TypeFromPrimitiveType(refType); } if (type == null) { SchemaObject obj = getWithName(parent, refType.getLocalPart()); types.add(ontRoot+getName(obj,"has")); } } if (types.size() > 0) { for (String type : types) { writer.print(" " + type); } } if (!single) { writer.println(ontRoot+name+ "List " + ontRoot+name+"List"); } } } @Override protected void handleIndicator(SchemaObject parent, SchemaElement indicator, SchemaElement element, String refName, RefType refType) { if (refType != refType.Element) { QName referenceType = null; if (refType == RefType.Type) { referenceType = element.getElement().getType(); //refName = element.getElement().getName() SchemaObject eObj = elements.get(element.getElement()); if (refName == null) refName = eObj.getName(); } else { referenceType = element.getElement().getRef(); if (refName == null) refName = referenceType.getLocalPart(); } String type = getL0TypeFromPrimitiveType(referenceType); SchemaObject obj = null; if (type == null) { obj = getWithName(parent, referenceType.getLocalPart()); writer.println(ontRoot+getName(parent)+".has"+refName + " " + ontRoot+getName(obj)); } else { writer.println(ontRoot+getName(parent)+".has"+refName + " " + getType(referenceType)); } if (useElementList(parent, indicator,element, refType == RefType.Reference, refName, referenceType)) { if (type == null) { writer.println(ontRoot+getName(parent)+"."+refName + "List " + ontRoot+getName(obj)); if (useElementList(parent, indicator,element, false, refName, new QName(obj.getName()))) { writer.println(ontRoot+getName(parent)+"."+refName + "List element = (JAXBElement)facetWrap; // QName elementName = element.getName(); // Facet facet = (Facet)element.getValue(); // } } writer.println(relationName+ " " + ontType); } else if (primitiveType != null) { writer.println(" attributes) { Attribute compositionAttribute = new Attribute(); compositionAttribute.setName(composition.getName()); QName type = new QName(CONVERSION_NS, composition.getType()); compositionAttribute.setType(type); handle(parent, compositionAttribute); } @Override protected void handleSimpleType(SchemaObject parent, SchemaObject simpleTypeObj) { SimpleType simpleType = simpleTypeObj.getSimpleType(); String name = simpleType.getName(); org.w3._2001.xmlschema.List list = simpleType.getList(); if (list != null) { // TODO : process restriction in lists String relationName = ontRoot+"has"+name; if (parent != null) relationName = ontRoot+getName(parent)+".has"+name; writer.println(relationName+ " " + ontType); } else { Restriction restriction = simpleType.getRestriction(); if (restriction == null || simpleType.getUnion() != null || simpleType.getId() != null) throw new RuntimeException(simpleType.getName() + " restriction error"); QName base = restriction.getBase(); String relationName = ontRoot+"has"+name; if (parent != null) relationName = ontRoot+getName(parent)+".has"+name; writer.println(relationName+ " " + ontType); } } @Override protected void handleComplexType(SchemaObject topLevelComplexType) { String name = getName(topLevelComplexType); // if (topLevelComplexType.getName().equals("Reference")) // System.out.println(); String relationName = ontRoot+getName(topLevelComplexType,"has");//ontRoot+"has"+name; writer.println(relationName+ " " + ontRoot+getComplexTypePrefix()+name); writer.println(" --> " + ontRoot+name); writer.println(); String baseType = "XML.ComplexType"; QName base = getComplexTypeBase(topLevelComplexType.getComplexType()); if (base != null) { baseType = getType(base); } base = getSimpleTypeBase(topLevelComplexType.getSimpleType()); if (base != null) { baseType = getType(base); } //writer.println(ontRoot+getComplexTypePrefix()+name+ " types = new LinkedHashSet(); if (element.getType() != null) { types.add(getType(element.getType())); } QName base = getElementBase(element); if (base != null) { if (base.getNamespaceURI().equals(SCHEMA_NS)) { String l0Type = getL0Type(base); if (l0Type == null) throw new RuntimeException("Cannot get L0 type for " + base.getLocalPart()); types.add(l0Type); } else if (isElementRef(base.getLocalPart())) types.add(ontRoot+base.getLocalPart()); else types.add(ontRoot+getComplexTypePrefix()+base.getLocalPart()); } QName substitution = element.getSubstitutionGroup(); if (substitution != null) { if (isElementRef(substitution.getLocalPart())) types.add(ontRoot+substitution.getLocalPart()); else types.add( ontRoot+getComplexTypePrefix()+substitution.getLocalPart()); } for (String t : types) { type += " references = getIDReferences(element); for (IDReference ref : references) { writer.println(ontRoot+name+"."+ref.getReference().getName()+ "