]> gerrit.simantics Code Review - simantics/interop.git/blobdiff - org.simantics.xml.sax/src/org/simantics/xml/sax/SchemaConversionBase.java
XML Schema converter
[simantics/interop.git] / org.simantics.xml.sax / src / org / simantics / xml / sax / SchemaConversionBase.java
diff --git a/org.simantics.xml.sax/src/org/simantics/xml/sax/SchemaConversionBase.java b/org.simantics.xml.sax/src/org/simantics/xml/sax/SchemaConversionBase.java
new file mode 100644 (file)
index 0000000..f35a884
--- /dev/null
@@ -0,0 +1,936 @@
+package org.simantics.xml.sax;\r
+\r
+import java.util.ArrayDeque;\r
+import java.util.ArrayList;\r
+import java.util.Deque;\r
+import java.util.HashMap;\r
+import java.util.HashSet;\r
+import java.util.List;\r
+import java.util.Map;\r
+import java.util.Set;\r
+\r
+import javax.xml.bind.JAXBElement;\r
+import javax.xml.namespace.QName;\r
+\r
+import org.simantics.utils.datastructures.BijectionMap;\r
+import org.simantics.xml.sax.SchemaElement.ElementType;\r
+import org.simantics.xml.sax.SchemaObject.ObjectType;\r
+import org.simantics.xml.sax.configuration.AttributeComposition;\r
+import org.simantics.xml.sax.configuration.Configuration;\r
+import org.simantics.xml.sax.configuration.IDProvider;\r
+import org.simantics.xml.sax.configuration.IDReference;\r
+import org.simantics.xml.sax.configuration.OrderedChild;\r
+import org.simantics.xml.sax.configuration.UnrecognizedChildElement;\r
+import org.w3._2001.xmlschema.All;\r
+import org.w3._2001.xmlschema.Annotated;\r
+import org.w3._2001.xmlschema.Any;\r
+import org.w3._2001.xmlschema.Attribute;\r
+import org.w3._2001.xmlschema.AttributeGroup;\r
+import org.w3._2001.xmlschema.ComplexContent;\r
+import org.w3._2001.xmlschema.ComplexType;\r
+import org.w3._2001.xmlschema.Element;\r
+import org.w3._2001.xmlschema.ExplicitGroup;\r
+import org.w3._2001.xmlschema.ExtensionType;\r
+import org.w3._2001.xmlschema.LocalComplexType;\r
+import org.w3._2001.xmlschema.LocalElement;\r
+import org.w3._2001.xmlschema.NamedAttributeGroup;\r
+import org.w3._2001.xmlschema.OpenAttrs;\r
+import org.w3._2001.xmlschema.Restriction;\r
+import org.w3._2001.xmlschema.Schema;\r
+import org.w3._2001.xmlschema.SimpleType;\r
+import org.w3._2001.xmlschema.TopLevelAttribute;\r
+import org.w3._2001.xmlschema.TopLevelComplexType;\r
+import org.w3._2001.xmlschema.TopLevelElement;\r
+import org.w3._2001.xmlschema.TopLevelSimpleType;\r
+\r
+public abstract class SchemaConversionBase {\r
+       \r
+       protected Schema schema;\r
+       protected Configuration configuration;\r
+       \r
+       protected static final String SCHEMA_NS = "http://www.w3.org/2001/XMLSchema";\r
+       protected static final String CONVERSION_NS = "http://www.simantics.org/Layer0";\r
+       \r
+       protected Map<String,Map<String,TypeEntry>> typeMap;\r
+       \r
+       public SchemaConversionBase(Configuration configuration) {\r
+               this.configuration = configuration;\r
+               typeMap = new HashMap<String, Map<String,TypeEntry>>();\r
+               \r
+               Map<String,TypeEntry> schemaTypes = new HashMap<String, SchemaConversionBase.TypeEntry>();\r
+               typeMap.put(SCHEMA_NS, schemaTypes);\r
+               Map<String,TypeEntry> l0Types = new HashMap<String, SchemaConversionBase.TypeEntry>();\r
+               typeMap.put(CONVERSION_NS, l0Types);\r
+               \r
+               schemaTypes.put("string",               new TypeEntry("L0.String",                      "STRING", "String", ""));\r
+               schemaTypes.put("NMTOKEN",              new TypeEntry("L0.String",                      "STRING", "String", ""));\r
+               schemaTypes.put("token",                new TypeEntry("L0.String",                      "STRING", "String", ""));\r
+               schemaTypes.put("ID",                   new TypeEntry("L0.String",                      "STRING", "String", "",true));\r
+               schemaTypes.put("IDREF",                new TypeEntry("L0.String",                      "STRING", "String", ""));\r
+               schemaTypes.put("date",                 new TypeEntry("L0.String",                      "STRING", "String", ""));\r
+               schemaTypes.put("time",                 new TypeEntry("L0.String",                      "STRING", "String", ""));\r
+               schemaTypes.put("anyURI",               new TypeEntry("L0.URI",                         "STRING", "String", ""));\r
+               schemaTypes.put("double",               new TypeEntry("L0.Double",                      "DOUBLE", "double", "Double.NaN"));\r
+               schemaTypes.put("float",                new TypeEntry("L0.Float",                       "FLOAT",  "float",  "Float.NaN"));\r
+               schemaTypes.put("decimal",              new TypeEntry("L0.Double",                      "DOUBLE", "double", "Double.NaN"));\r
+               schemaTypes.put("boolean",              new TypeEntry("L0.Boolean",                     "BOOLEAN", "boolean", "false"));\r
+               schemaTypes.put("integer",              new TypeEntry("L0.Integer",             "INTEGER", "int", "0"));\r
+               schemaTypes.put("positiveInteger", new TypeEntry("L0.Integer",          "INTEGER", "int", "0"));\r
+               schemaTypes.put("nonPositiveInteger", new TypeEntry("L0.Integer",       "INTEGER", "int", "0"));\r
+               schemaTypes.put("nonNegativeInteger", new TypeEntry("L0.Integer",       "INTEGER", "int", "0"));\r
+               schemaTypes.put("negativeInteger", new TypeEntry("L0.Integer",          "INTEGER", "int", "0"));\r
+               schemaTypes.put("unsignedInt",  new TypeEntry("L0.Integer",             "INTEGER", "int", "0"));\r
+               schemaTypes.put("int",                  new TypeEntry("L0.Integer",                     "INTEGER", "int", "0"));\r
+               schemaTypes.put("short",                new TypeEntry("L0.Integer",                     "INTEGER", "int", "0"));\r
+               schemaTypes.put("unsignedShort",new TypeEntry("L0.Integer",                     "INTEGER", "int", "0"));\r
+               schemaTypes.put("byte",                 new TypeEntry("L0.Byte",                        "BYTE", "byte", "0"));\r
+               schemaTypes.put("unsignedByte", new TypeEntry("L0.Byte",                        "BYTE", "byte", "0"));\r
+               schemaTypes.put("long",                 new TypeEntry("L0.Long",                        "LONG", "long", "0"));\r
+               schemaTypes.put("unsignedLong", new TypeEntry("L0.Long",                        "LONG", "long", "0"));\r
+               \r
+               \r
+               \r
+               l0Types.put("doubleArray",              new TypeEntry("L0.DoubleArray",  "DOUBLE_ARRAY", "double[]", null));\r
+               l0Types.put("stringArray",              new TypeEntry("L0.StringArray",  "STRING_ARRAY", "string[]", null));\r
+       }\r
+       \r
+       \r
+       protected TypeEntry getTypeEntry(QName type) {\r
+               Map<String,TypeEntry> types = typeMap.get(type.getNamespaceURI());\r
+               if (types == null)\r
+                       return null;\r
+               TypeEntry entry = types.get(type.getLocalPart());\r
+               return entry;\r
+               \r
+       }\r
+       \r
+       protected String getL0TypeFromPrimitiveType(QName primitiveType) {\r
+               TypeEntry entry = getTypeEntry(primitiveType);\r
+               if (entry == null)\r
+                       return null;\r
+               return entry.l0Type;\r
+       }\r
+       \r
+       protected String getL0Type(QName primitiveType) {\r
+               String type = getL0TypeFromPrimitiveType(primitiveType);\r
+               if (type != null)\r
+                       return type;\r
+               SchemaObject simpleTypeObj = simpleTypeName.get(primitiveType.getLocalPart());\r
+               if (simpleTypeObj == null)\r
+                       return null;\r
+               SimpleType simpleType = simpleTypeObj.getSimpleType();\r
+               while (simpleType != null) {\r
+                       QName base = simpleType.getRestriction().getBase();\r
+                       if (base != null)\r
+                               return getL0Type(base);\r
+                       simpleType = simpleType.getRestriction().getSimpleType();\r
+               }\r
+               return null;\r
+       }\r
+       \r
+       protected String getBindingFromPrimitiveType(QName primitiveType) {\r
+               TypeEntry entry = getTypeEntry(primitiveType);\r
+               if (entry == null)\r
+                       return null;\r
+               return entry.binding;\r
+       }\r
+       \r
+       protected String getJavaTypeFromPrimitiveType(QName primitiveType) {\r
+               TypeEntry entry = getTypeEntry(primitiveType);\r
+               if (entry == null)\r
+                       return null;\r
+               return entry.javaType;\r
+       }\r
+       \r
+       \r
+       protected void handle(Schema schema) {  \r
+               this.schema = schema;\r
+               preload();\r
+               \r
+               for (OpenAttrs attrs : schema.getSimpleTypeOrComplexTypeOrGroup()) {\r
+                       if (attrs instanceof TopLevelAttribute) {\r
+                               handle((TopLevelAttribute)attrs);\r
+                               \r
+                       } else if (attrs instanceof TopLevelComplexType) {\r
+                               handleComplexType(complexTypes.get(attrs));\r
+                       } else if (attrs instanceof TopLevelElement) {\r
+                               handleElement(elements.get(attrs));\r
+                       } else if (attrs instanceof TopLevelSimpleType) {\r
+                               handleSimpleType(simpleTypes.get(attrs));\r
+                       } else if (attrs instanceof NamedAttributeGroup) {\r
+                               handle((NamedAttributeGroup)attrs);\r
+                       } else {\r
+                               System.out.println(attrs.getClass().getName());\r
+                       }\r
+               }\r
+       }\r
+       \r
+       protected Map<String,SchemaObject> elementName = new HashMap<String, SchemaObject>();\r
+       protected Map<String,SchemaObject> complexTypeName = new HashMap<String, SchemaObject>();\r
+       protected Map<String,SchemaObject> simpleTypeName = new HashMap<String, SchemaObject>();\r
+       protected Map<Element,SchemaObject> elements = new HashMap<Element, SchemaObject>();\r
+       protected Map<ComplexType,SchemaObject> complexTypes = new HashMap<ComplexType, SchemaObject>();\r
+       protected Map<SimpleType,SchemaObject> simpleTypes = new HashMap<SimpleType, SchemaObject>();\r
+       \r
+       \r
+       protected SchemaObject getWithName(SchemaObject referrer, String name) {\r
+               SchemaObject obj = elementName.get(name);\r
+               if (obj == null)\r
+                       obj = complexTypeName.get(name);\r
+               if (obj == null)\r
+                       obj = simpleTypeName.get(name);\r
+               if (obj == null) {\r
+                       throw new RuntimeException("Cannot locate referred type " + name + " when handling " + referrer.getName());\r
+               }\r
+               return obj;\r
+       }\r
+       \r
+       protected SchemaObject getWithObj(SchemaObject referrer, OpenAttrs attrs) {\r
+               SchemaObject obj = null;\r
+               if (attrs instanceof Element)\r
+                       obj = elements.get(attrs);\r
+               else if (attrs instanceof ComplexType)\r
+                       obj = complexTypes.get(attrs);\r
+               else if (attrs instanceof SimpleType) \r
+                       obj = simpleTypes.get(attrs);\r
+               if (obj == null){\r
+                       throw new RuntimeException("Cannot locate referred object " + attrs + " when handling " + referrer.getName());\r
+               }\r
+               return obj;\r
+       }\r
+       \r
+       private void preload() {\r
+               Deque<SchemaObject> stack = new ArrayDeque<SchemaObject>();\r
+               //stack.addAll(schema.getSimpleTypeOrComplexTypeOrGroup());\r
+               for (OpenAttrs attrs : schema.getSimpleTypeOrComplexTypeOrGroup()) {\r
+                       if (attrs instanceof Element) {\r
+                               Element element = (Element)attrs;\r
+                               SchemaObject obj = new SchemaObject(element);\r
+                               stack.push(obj);\r
+                       } else if (attrs instanceof ComplexType) {\r
+                               ComplexType complexType = (ComplexType)attrs;\r
+                               SchemaObject obj = new SchemaObject(complexType);\r
+                               stack.push(obj);\r
+                       } else if (attrs instanceof SimpleType) {\r
+                               SimpleType simpleType = (SimpleType)attrs;\r
+                               SchemaObject obj = new SchemaObject(simpleType);\r
+                               stack.push(obj);\r
+                       }\r
+               }\r
+               \r
+               while (!stack.isEmpty()) {\r
+                       SchemaObject object = stack.pop();\r
+                       if (object.getType() == ObjectType.COMPLEX_TYPE) {\r
+                               ComplexType ct = object.getComplexType();\r
+                               if (ct.getName() != null && ct.getName().length() > 0 && ct instanceof TopLevelComplexType)\r
+                                       complexTypeName.put(ct.getName(), object);\r
+                               complexTypes.put(ct, object);\r
+                               if (ct.getChoice() != null) {\r
+                                       preload(object,ct.getChoice(), stack);\r
+                               }\r
+                               if (ct.getSequence() != null) {\r
+                                       preload(object,ct.getSequence(), stack);\r
+                               }\r
+                               if (ct.getAll() != null) {\r
+                                       preload(object,ct.getAll(), stack);\r
+                               }\r
+                               if (ct.getGroup() != null)\r
+                                       throw new RuntimeException("Groups not supported");\r
+                               if (ct.getComplexContent() != null) {\r
+                                       ComplexContent cc = ct.getComplexContent();\r
+                                       ExtensionType extensionType = cc.getExtension();\r
+                                       if (extensionType != null) {\r
+                                               if (extensionType.getChoice() != null) {\r
+                                                       preload(object,extensionType.getChoice(), stack);\r
+                                               }\r
+                                               if (extensionType.getSequence()!= null) {\r
+                                                       preload(object,extensionType.getSequence(), stack);\r
+                                               }\r
+                                               if (extensionType.getAll()!= null) {\r
+                                                       preload(object,extensionType.getAll(), stack);\r
+                                               }\r
+                                               if (extensionType.getGroup() != null)\r
+                                                       throw new RuntimeException("Groups not supported");\r
+                                       }\r
+                               }\r
+                       } else if (object.getType() == ObjectType.ELEMENT) {\r
+                               Element e = object.getElement();\r
+                               if (e instanceof TopLevelElement)\r
+                                       elementName.put(e.getName(), object);\r
+                               elements.put(e, object);\r
+                               if (e.getComplexType() != null)\r
+                                       stack.push(new SchemaObject(object,e.getComplexType()));\r
+                               if (e.getSimpleType() != null)\r
+                                       stack.push(new SchemaObject(object,e.getSimpleType()));\r
+                       } else if (object.getType() == ObjectType.SIMPLE_TYPE) {\r
+                               SimpleType e = object.getSimpleType();\r
+                               if (e instanceof TopLevelSimpleType)\r
+                                       simpleTypeName.put(e.getName(), object);\r
+                               simpleTypes.put(e, object);\r
+                       }\r
+               }\r
+       }\r
+       \r
+       private void preload(SchemaObject parent,ExplicitGroup eg, Deque<SchemaObject> stack) {\r
+               for (Object o : eg.getParticle()) {\r
+                       if (o instanceof JAXBElement<?>) {\r
+                               JAXBElement<?> element = (JAXBElement<?>)o;\r
+                               Object elemValue = element.getValue();\r
+                               if (elemValue instanceof Element) {\r
+                                       stack.add(new SchemaObject(parent,(Element)elemValue));\r
+                               } else if (elemValue instanceof All) {\r
+                                       preload(parent,(All)elemValue, stack);\r
+                               } else if (elemValue instanceof ExplicitGroup) {\r
+                                       preload(parent,(ExplicitGroup)elemValue, stack);\r
+                               } else {\r
+                                       throw new RuntimeException("Unknown ExplicitGroup element " + elemValue.getClass().getName());\r
+                               }\r
+                       } else if (o instanceof Any){\r
+                               \r
+                       } else {\r
+                               throw new RuntimeException("Unknown ExplicitGroup reference " + o.getClass().getName());\r
+                       }\r
+               }\r
+       }\r
+       \r
+       protected void handle(TopLevelAttribute topLevelAttribute) {\r
+               handle(null, topLevelAttribute);\r
+       }\r
+       \r
+       protected void handleSimpleType(SchemaObject topLevelSimpleType) {\r
+               handleSimpleType(null,topLevelSimpleType);\r
+       }\r
+       \r
+       protected void handle(NamedAttributeGroup namedAttributeGroup){\r
+               handle(null, namedAttributeGroup);\r
+       }\r
+       \r
+       protected QName getComplexTypeBase(ComplexType complexType) {\r
+               if (complexType == null)\r
+                       return null;\r
+               ComplexContent complexContent = complexType.getComplexContent();\r
+               if (complexContent != null) {\r
+                       ExtensionType extensionType = complexContent.getExtension();\r
+                       if (extensionType != null) {\r
+                               QName type = extensionType.getBase();\r
+                               return type;\r
+                       }\r
+               }\r
+               return null;\r
+       }\r
+       \r
+       protected QName getSimpleTypeBase(SimpleType simpleType) {\r
+               if (simpleType == null)\r
+                       return null;\r
+               return simpleType.getRestriction().getBase();\r
+       }\r
+       \r
+       protected QName getElementBase(Element element) {\r
+               ComplexType complexType = element.getComplexType();\r
+               SimpleType simpleType = element.getSimpleType();\r
+               if (complexType != null)\r
+                       return getComplexTypeBase(complexType);\r
+               if (simpleType != null) {\r
+                       return getSimpleTypeBase(simpleType);\r
+               }\r
+               return null;\r
+       }\r
+       \r
+\r
+       \r
+       \r
+       \r
+       \r
+       \r
+       \r
+       private void handleAttributes(SchemaObject complexType, List<Annotated> attributeOrAttributeGroup) {\r
+               //name = getComplexTypePrefix()+complexType.getName()\r
+               \r
+               Set<Annotated> handled = handleAttributeCompositions(complexType,attributeOrAttributeGroup);\r
+               for (Annotated annotated : attributeOrAttributeGroup) {\r
+                       if (handled.contains(annotated))\r
+                               continue;\r
+                       if (annotated instanceof Attribute) {\r
+                               handle(complexType,(Attribute)annotated);\r
+                       } else if (annotated instanceof AttributeGroup){\r
+                               handle(complexType,(AttributeGroup)annotated);\r
+                               //comment("AttributeGroup " + ((AttributeGroup)annotated).getRef().getLocalPart());\r
+                       } else {\r
+                               throw new RuntimeException();\r
+                       }\r
+               }\r
+       }\r
+       \r
+       protected abstract void handleAttributes(SchemaObject simpleTypeObj);\r
+       \r
+       protected void handleExtensionAttributes(SchemaObject complexType) {\r
+               ComplexContent complexContent = complexType.getComplexType().getComplexContent();\r
+               if (complexContent != null) {\r
+                       ExtensionType extensionType = complexContent.getExtension();\r
+                       if (extensionType != null) {\r
+                               handleAttributes(complexType, extensionType.getAttributeOrAttributeGroup());\r
+                       }\r
+               }\r
+       }\r
+       \r
+       \r
+       \r
+       protected void handleComplexTypeAttributes(SchemaObject complexType) {          \r
+               handleAttributes(complexType,complexType.getComplexType().getAttributeOrAttributeGroup());\r
+       }\r
+       \r
+       protected void handleElementComplexTypeAttributes(SchemaObject complexType) {\r
+               if (complexType != null) {\r
+                       handleComplexTypeAttributes(complexType);\r
+                       handleExtensionAttributes(complexType);\r
+               }\r
+       }\r
+       \r
+       protected void handleElementSimpleTypeAttributes(SchemaObject simpleType) {\r
+               if (simpleType != null) {\r
+                       handleAttributes(simpleType);\r
+               }\r
+       }\r
+       \r
+       protected Set<Annotated> handleAttributeCompositions(SchemaObject obj, List<Annotated> attributeOrAttributeGroup) {\r
+               \r
+               Set<Annotated> handled = new HashSet<Annotated>();\r
+               for (JAXBElement<?> e : configuration.getConversionRule()) {\r
+                       if (e.getValue() instanceof AttributeComposition) {\r
+                               AttributeComposition composition = (AttributeComposition)e.getValue();\r
+                               if (composition.getAttribute().size() < 2)\r
+                                       throw new RuntimeException("Attribute Composition is not valid");\r
+                               BijectionMap<org.simantics.xml.sax.configuration.Attribute, Annotated> map = new BijectionMap<org.simantics.xml.sax.configuration.Attribute, Annotated>();\r
+                               for (org.simantics.xml.sax.configuration.Attribute a : composition.getAttribute()) {\r
+                                       for (Annotated annotated : attributeOrAttributeGroup) {\r
+                                               if (annotated instanceof Attribute) {\r
+                                                       Attribute attribute = (Attribute)annotated;\r
+                                                       QName type = getBaseType(attribute);\r
+                                                       if (a.getName().equals(attribute.getName()) && type != null && a.getType().equals(type.getLocalPart())) {\r
+                                                               map.map(a, attribute);\r
+                                                       }\r
+                                               }\r
+                                       }\r
+                               }\r
+                               if (composition.getAttribute().size() == map.size()) {\r
+                                       handled.addAll(map.getRightSet());\r
+                                       handleAttributeComposition(obj, composition, map);      \r
+                               }\r
+                       }\r
+               }\r
+               return handled;\r
+       }\r
+       \r
+       protected QName getBaseType(Attribute attribute) {\r
+               if (attribute.getType() != null)\r
+                       return attribute.getType();\r
+               if (attribute.getRef() != null)\r
+                       return attribute.getRef();\r
+               SimpleType simpleType = attribute.getSimpleType();\r
+               if (simpleType != null) {\r
+                       Restriction restriction = simpleType.getRestriction();\r
+                       if (restriction != null)\r
+                               if (restriction.getBase() != null)\r
+                                       return restriction.getBase();\r
+               }\r
+               return null;\r
+       }\r
+       \r
+       protected Attribute getRefAttribute(QName ref) {\r
+               for (OpenAttrs attrs : schema.getSimpleTypeOrComplexTypeOrGroup()) {\r
+                       if (attrs instanceof TopLevelAttribute) {\r
+                               TopLevelAttribute attribute = (TopLevelAttribute)attrs;\r
+                               if (attribute.getName().equals(ref.getLocalPart()))\r
+                                       return attribute;\r
+                       }\r
+               }\r
+               return null;\r
+       }\r
+       \r
+       protected abstract void handleAttributeComposition(SchemaObject obj, AttributeComposition composition, BijectionMap<org.simantics.xml.sax.configuration.Attribute, Annotated> attributes);\r
+       \r
+       \r
+       \r
+       \r
+       protected void handleComplexType(SchemaObject complexType) {\r
+               handleComplexTypeAttributes(complexType);\r
+               handleComplexTypeExtension(complexType);\r
+               handleExtensionAttributes(complexType);\r
+       }\r
+       \r
+       protected abstract void handleIndicator(SchemaObject parent, SchemaElement indicator, SchemaElement element, boolean reference, String refName, QName refType);\r
+       protected abstract void handleIndicator(SchemaObject parent, SchemaElement indicator, SchemaElement element, boolean reference, String refName, OpenAttrs ref);\r
+       protected abstract void handleIndicator(SchemaObject parent, SchemaElement indicator, SchemaElement any);\r
+       protected abstract void handle(SchemaObject parent, SchemaElement indicator, List<SchemaElement> elements);\r
+       \r
+       protected void handle(SchemaObject parent, ExplicitGroup eg, SchemaElement.ElementType indicator) {\r
+               handle(parent, new SchemaElement(eg, indicator));\r
+       }\r
+       \r
+       protected void handle(SchemaObject parent, SchemaElement indicator) {\r
+               \r
+               \r
+               List<SchemaElement> elements = new ArrayList<SchemaElement>();\r
+               List<SchemaElement> choices = new ArrayList<SchemaElement>();\r
+               List<SchemaElement> sequences = new ArrayList<SchemaElement>();\r
+               List<SchemaElement> alls = new ArrayList<SchemaElement>();\r
+               List<SchemaElement> anys = new ArrayList<SchemaElement>();\r
+               \r
+               for (Object o : indicator.getGroup().getParticle()) {\r
+                       if (o instanceof JAXBElement<?>) {\r
+                               JAXBElement<?> element = (JAXBElement<?>)o;\r
+                               Object elemValue = element.getValue();\r
+                               if (elemValue instanceof LocalElement) {\r
+                                       LocalElement localElement = (LocalElement)elemValue;\r
+                                       \r
+                                       elements.add(new SchemaElement(indicator,localElement, ElementType.ELEMENT));\r
+                               } else if (elemValue instanceof All) {\r
+                                       alls.add(new SchemaElement(indicator,(All)elemValue, ElementType.ALL));\r
+                               } else if (elemValue instanceof ExplicitGroup) {\r
+                                       QName qname = element.getName();\r
+                                       if ("choice".equals(qname.getLocalPart())) {\r
+                                               choices.add(new SchemaElement(indicator,(ExplicitGroup)elemValue, ElementType.CHOICE));\r
+                                       } else if ("sequence".equals(qname.getLocalPart())) {\r
+                                               sequences.add(new SchemaElement(indicator,(ExplicitGroup)elemValue, ElementType.SEQUENCE));\r
+                                       }\r
+                               } else {\r
+                                       throw new RuntimeException("Unknown ExplicitGroup element " + elemValue.getClass().getName());\r
+                               }\r
+                       } else if (o instanceof Any){\r
+                               anys.add(new SchemaElement(indicator,(Any)o, ElementType.ANY));\r
+                       } else {\r
+                               throw new RuntimeException("Unknown ExplicitGroup reference " + o.getClass().getName());\r
+                       }\r
+               }\r
+               \r
+               if (elements.size() == 0 && choices.size() == 0 && sequences.size() == 0 && alls.size() == 0 && anys.size() == 0) {\r
+                       return;\r
+               }\r
+               \r
+               if (indicator.getType() == SchemaElement.ElementType.SEQUENCE) {\r
+                       if (indicator.getRestriction().single()) {\r
+                               if (elements.size() > 0) {\r
+                                       for (SchemaElement e : sequences) {\r
+                                               handle(parent, e);\r
+                                       }\r
+                                       for (SchemaElement c : choices) {\r
+                                               handle(parent, c);\r
+                                       }\r
+                                       \r
+                                       for (SchemaElement c : alls) {\r
+                                               handle(parent, c);\r
+                                       }\r
+                                       handle(parent, indicator, elements);\r
+                                       for (SchemaElement a : anys) {\r
+                                               handleIndicator(parent, indicator, a);\r
+                                       }\r
+                               } else {\r
+                                       if (sequences.size() > 0) {\r
+                                               throw new RuntimeException("Cannot handle Sequence with inner Sequences");\r
+                                       }\r
+                                       for (SchemaElement c : choices) {\r
+                                               handle(parent, c);\r
+                                       }\r
+                                       for (SchemaElement a : anys) {\r
+                                               handleIndicator(parent, indicator, a);\r
+                                       }\r
+                               }\r
+                       } else {\r
+                               if (sequences.size() > 0 || choices.size() > 0 || alls.size() > 0) {\r
+                                       throw new RuntimeException("Cannot handle Sequence with inner ExplicitGroups");\r
+                               }\r
+                               handle(parent, indicator, elements);\r
+                               for (SchemaElement a : anys) {\r
+                                       handleIndicator(parent, indicator, a);\r
+                               }\r
+                       }\r
+               \r
+               } else if (indicator.getType() == SchemaElement.ElementType.CHOICE){\r
+                       if (indicator.getRestriction().single()) {\r
+                               if (sequences.size()> 0 || choices.size() > 0 || alls.size() > 0 || anys.size() > 0) {\r
+                                       throw new RuntimeException("Cannot handle Choice that contains something else than Elements");\r
+                               }\r
+                               handle(parent, indicator, elements);\r
+                               \r
+                       } else {\r
+                               if (sequences.size() > 0 || choices.size() > 0) {\r
+                                       throw new RuntimeException("Cannot handle Choice with inner ExplicitGroups");\r
+                               }\r
+                               handle(parent, indicator,  elements);\r
+                               for (SchemaElement a : anys) {\r
+                                       handleIndicator(parent, indicator, a);\r
+                               }\r
+                       }\r
+               } else if (indicator.getType() == ElementType.ALL) {\r
+                       if (sequences.size()> 0 || choices.size() > 0 || alls.size() > 0 || anys.size() > 0) {\r
+                               throw new RuntimeException("Cannot handle All that contains something else than Elements");\r
+                       }\r
+                       if (!indicator.getRestriction().single()) {\r
+                               throw new RuntimeException("All indicator must have maxOccurs=1");\r
+                       }\r
+                       handle(parent, indicator, elements);\r
+               }\r
+       }\r
+       \r
+       \r
+       protected void handle(SchemaObject parent, SchemaElement indicator, SchemaElement element) {\r
+               Element localElement = element.getElement();\r
+               if (localElement.getName() != null) {\r
+                       String refName = localElement.getName();\r
+                       QName refType = localElement.getType();\r
+                       if (refType != null)\r
+                               handleIndicator(parent, indicator, element, false, refName, refType);\r
+                       else {\r
+                               handleElement(elements.get(localElement));\r
+                               handleIndicator(parent, indicator, element, false, refName, localElement);\r
+                               //FIXME:\r
+                       }\r
+               } else if (localElement.getRef() != null) {\r
+                       QName refType = localElement.getRef();\r
+                       handleIndicator(parent, indicator,element, true, refType.getLocalPart(), refType);\r
+               }\r
+       }\r
+       \r
+       protected String getElementName(Element localElement) {\r
+               if (localElement.getName() != null) {\r
+                       String refName = localElement.getName();\r
+                       QName refType = localElement.getType();\r
+                       if (refType != null)\r
+                               return refName;\r
+               } else if (localElement.getRef() != null) {\r
+                       QName refType = localElement.getRef();\r
+                       if (refType != null)\r
+                               return refType.getLocalPart();\r
+               }\r
+               return null;\r
+       }\r
+       \r
+       protected String getChoiceName(List<SchemaElement> elements) {\r
+               if (elements.size() == 1) {\r
+                       return getElementName(elements.get(0).getElement());\r
+               }\r
+               List<String> names = new ArrayList<String>();\r
+               for (SchemaElement e : elements) {\r
+                       String name = getElementName(e.getElement());\r
+                       if (name != null)\r
+                               names.add(name);\r
+               }\r
+               String name = "";\r
+               for (int i = 0; i < names.size(); i++) {\r
+                       if (i == 0)\r
+                               name = names.get(i);\r
+                       else\r
+                               name += "Or"+names.get(i);\r
+               }\r
+               return name;\r
+       }\r
+       \r
+       \r
+       protected abstract void handle(SchemaObject parent, Attribute attribute) ;\r
+       protected abstract void handle(SchemaObject parent, AttributeGroup attribute) ;\r
+       \r
+       protected abstract void handleSimpleType(SchemaObject parent, SchemaObject simpleType);\r
+       \r
+       \r
+       \r
+       protected void handleComplexTypeExtension(SchemaObject complexTypeObj) {\r
+               ComplexType complexType = complexTypeObj.getComplexType();\r
+               if (complexType != null) {\r
+                       if (complexType.getChoice() != null)\r
+                               handle(complexTypeObj, complexType.getChoice(), SchemaElement.ElementType.CHOICE);\r
+                       if (complexType.getSequence() != null)\r
+                               handle(complexTypeObj, complexType.getSequence(), SchemaElement.ElementType.SEQUENCE);\r
+                       if (complexType.getAll() != null)\r
+                               handle(complexTypeObj, complexType.getAll(), SchemaElement.ElementType.ALL);\r
+                       if (complexType.getGroup() != null)\r
+                               throw new RuntimeException("Groups not supported");\r
+                       ComplexContent complexContent = complexType.getComplexContent();\r
+                       if (complexContent != null) {\r
+                               ExtensionType extensionType = complexContent.getExtension();\r
+                               if (extensionType != null) {\r
+                                       if (extensionType.getChoice() != null) {\r
+                                               handle(complexTypeObj, extensionType.getChoice(), SchemaElement.ElementType.CHOICE);\r
+                                       }\r
+                                       if (extensionType.getSequence()!= null) {\r
+                                               handle(complexTypeObj, extensionType.getSequence(), SchemaElement.ElementType.SEQUENCE);\r
+                                       }\r
+                                       if (extensionType.getAll()!= null) {\r
+                                               handle(complexTypeObj, extensionType.getAll(), SchemaElement.ElementType.ALL);\r
+                                       }\r
+                                       if (extensionType.getGroup() != null) {\r
+                                               throw new RuntimeException("Groups not supported");\r
+                                       }\r
+                               }\r
+                       }\r
+               }\r
+       }\r
+       \r
+       protected void handleElement(SchemaObject topLevelElement) {\r
+               LocalComplexType complexType = topLevelElement.getElement().getComplexType();\r
+               \r
+               if (complexType != null) {\r
+                       SchemaObject complextTypeObj = complexTypes.get(complexType);\r
+                       handleElementComplexTypeAttributes(complextTypeObj);\r
+                       handleComplexTypeExtension(complextTypeObj);\r
+               }\r
+               \r
+               \r
+       }\r
+       \r
+       \r
+       protected boolean isElementRef(String ref) {\r
+//             for (OpenAttrs attrs : schema.getSimpleTypeOrComplexTypeOrGroup()) {\r
+//                     if (attrs instanceof TopLevelElement) {\r
+//                             TopLevelElement element = (TopLevelElement)attrs;\r
+//                             if (ref.equals(element.getName()))\r
+//                                     return true;\r
+//                     }\r
+//             }\r
+//             return false;\r
+               return elementName.containsKey(ref);\r
+       }\r
+       \r
+       protected boolean isComplexTypeRef(String ref) {\r
+//             for (OpenAttrs attrs : schema.getSimpleTypeOrComplexTypeOrGroup()) {\r
+//                     if (attrs instanceof TopLevelComplexType) {\r
+//                             TopLevelComplexType element = (TopLevelComplexType)attrs;\r
+//                             if (ref.equals(element.getName()))\r
+//                                     return true;\r
+//                     }\r
+//             }\r
+//             return false;\r
+               return complexTypeName.containsKey(ref);\r
+               \r
+       }\r
+       \r
+       protected NamedAttributeGroup getAttributeGroup(String name) {\r
+               for (OpenAttrs attrs : schema.getSimpleTypeOrComplexTypeOrGroup()) {\r
+                       if (attrs instanceof NamedAttributeGroup) {\r
+                               NamedAttributeGroup group = (NamedAttributeGroup)attrs;\r
+                               if (group.getName().equals(name))\r
+                                       return group;\r
+                       }\r
+               }\r
+               return null;\r
+       }\r
+       \r
+       protected IDProvider getIDProvider(Element element) {\r
+               List<IDProvider> idProviders = new ArrayList<IDProvider>(2);\r
+               for (JAXBElement<?> e : configuration.getConversionRule()) {\r
+                       if (e.getValue() instanceof IDProvider) {\r
+                               IDProvider ref = (IDProvider)e.getValue();\r
+                               org.simantics.xml.sax.configuration.Element element2 = ref.getElement();\r
+                               if (element2 != null) {\r
+                                       if (element.getName().equals(element2.getName()))\r
+                                               idProviders.add(ref);\r
+                               }\r
+                               \r
+                       }\r
+               }\r
+               if (idProviders.size() == 0)\r
+                       return null;\r
+               if (idProviders.size() > 1)\r
+                       throw new RuntimeException("Element " + element.getName() + " contains " + idProviders.size() + " id provider rules, only one is allowed.");\r
+               return idProviders.get(0);\r
+       }\r
+       \r
+       protected IDProvider getIDProvider(ComplexType complexType) {\r
+               List<IDProvider> idProviders = new ArrayList<IDProvider>(2);\r
+               for (JAXBElement<?> e : configuration.getConversionRule()) {\r
+                       if (e.getValue() instanceof IDProvider) {\r
+                               IDProvider ref = (IDProvider)e.getValue();\r
+                               org.simantics.xml.sax.configuration.ComplexType complexType2 = ref.getComplexType();\r
+                               if (complexType2 != null) {\r
+                                       if (complexType.getName().equals(complexType2.getName()))\r
+                                               idProviders.add(ref);\r
+                               }\r
+\r
+                       }\r
+               }\r
+               if (idProviders.size() == 0)\r
+                       return null;\r
+               if (idProviders.size() > 1)\r
+                       throw new RuntimeException("Element " + complexType.getName() + " contains " + idProviders.size() + " id provider rules, only one is allowed.");\r
+               return idProviders.get(0);\r
+       }\r
+       \r
+       protected List<IDReference> getIDReferences(Element element) {\r
+               List<IDReference> idReferences = new ArrayList<IDReference>(2);\r
+               for (JAXBElement<?> e : configuration.getConversionRule()) {\r
+                       if (e.getValue() instanceof IDReference) {\r
+                               IDReference ref = (IDReference)e.getValue();\r
+                               org.simantics.xml.sax.configuration.Element element2 = ref.getElement();\r
+                               if (element2 != null) {\r
+                                       if (element.getName().equals(element2.getName()))\r
+                                               idReferences.add(ref);\r
+                               }\r
+                       }\r
+               }\r
+               return idReferences;\r
+       }\r
+       \r
+       protected List<IDReference> getIDReferences(ComplexType complexType) {\r
+               List<IDReference> idReferences = new ArrayList<IDReference>(2);\r
+               for (JAXBElement<?> e : configuration.getConversionRule()) {\r
+                       if (e.getValue() instanceof IDReference) {\r
+                               IDReference ref = (IDReference)e.getValue();\r
+                               org.simantics.xml.sax.configuration.ComplexType complexType2 = ref.getComplexType();\r
+                               if (complexType2 != null) {\r
+                                       if (complexType.getName().equals(complexType2.getName()))\r
+                                               idReferences.add(ref);\r
+                               }\r
+                       }\r
+               }\r
+               return idReferences;\r
+       }\r
+       \r
+       public UnrecognizedChildElement getUnknown(ComplexType complexType) {\r
+               for (JAXBElement<?> e : configuration.getConversionRule()) {\r
+                       if (e.getValue() instanceof UnrecognizedChildElement) {\r
+                               UnrecognizedChildElement ref = (UnrecognizedChildElement)e.getValue();\r
+                               org.simantics.xml.sax.configuration.ComplexType complexType2 = ref.getComplexType();\r
+                               if (complexType2 != null) {\r
+                                       if (complexType.getName().equals(complexType2.getName()))\r
+                                               return ref;\r
+                               }\r
+                       }\r
+               }\r
+               return null;\r
+       }\r
+       \r
+       public UnrecognizedChildElement getUnknown(Element element) {\r
+               for (JAXBElement<?> e : configuration.getConversionRule()) {\r
+                       if (e.getValue() instanceof UnrecognizedChildElement) {\r
+                               UnrecognizedChildElement ref = (UnrecognizedChildElement)e.getValue();\r
+                               org.simantics.xml.sax.configuration.Element element2 = ref.getElement();\r
+                               if (element2 != null) {\r
+                                       if (element.getName().equals(element2.getName()))\r
+                                               return ref;\r
+                               }\r
+                       }\r
+               }\r
+               return null;\r
+       }\r
+       \r
+       \r
+       public boolean useOriginalList(SchemaObject parent, SchemaElement indicator, SchemaElement element,  boolean reference, String ref, QName refType) {\r
+               if (parent.getName() == null)\r
+                       parent = parent.getParent();\r
+               if (parent.getName().contains("PipingNetworkSegment"))\r
+                       System.out.println();\r
+               for (JAXBElement<?> e : configuration.getConversionRule()) {\r
+                       if (e.getValue() instanceof OrderedChild) {\r
+                               OrderedChild oc = (OrderedChild)e.getValue();\r
+                               org.simantics.xml.sax.configuration.Element element2 = oc.getElement();\r
+                               org.simantics.xml.sax.configuration.ComplexType complexType = oc.getComplexType();\r
+                               org.simantics.xml.sax.configuration.Element child = oc.getChild();\r
+                               if (!oc.getType().equals("original"))\r
+                                       continue;\r
+                               boolean match = false;\r
+                               if (element2 != null) {\r
+                                       if (parent.getType() == ObjectType.ELEMENT && parent.getName().equals(element2.getName())) {\r
+                                               match = true;\r
+                                       }\r
+                               } else if (complexType != null) {\r
+                                       if (parent.getType() == ObjectType.COMPLEX_TYPE && parent.getName() != null && parent.getName().equals(complexType.getName())) {\r
+                                               match = true;\r
+                                       }\r
+                                       \r
+                               }\r
+                               if (match) {\r
+                                       if (child != null) {\r
+                                               if (matchChild(child, ref, refType)) {\r
+                                                       if (oc.getValue().equals("disable"))\r
+                                                               return false;\r
+                                                       else return true;\r
+                                               }\r
+                                       } else { \r
+                                               if (oc.getValue().equals("disable"))\r
+                                                       return false;\r
+                                               return true;\r
+                                       }\r
+                                       \r
+                               }\r
+                       }\r
+               }\r
+               return indicator.order();\r
+       }\r
+       \r
+       public boolean useElementList(SchemaObject parent, SchemaElement indicator, SchemaElement element,  boolean reference, String refName, QName refType) {\r
+               if (parent.getName() == null)\r
+                       parent = parent.getParent();\r
+               if (parent.getName() == "PipingNetworkSegment")\r
+                       System.out.println();\r
+               for (JAXBElement<?> e : configuration.getConversionRule()) {\r
+                       if (e.getValue() instanceof OrderedChild) {\r
+                               OrderedChild oc = (OrderedChild)e.getValue();\r
+                               org.simantics.xml.sax.configuration.Element element2 = oc.getElement();\r
+                               org.simantics.xml.sax.configuration.ComplexType complexType = oc.getComplexType();\r
+                               org.simantics.xml.sax.configuration.Element child = oc.getChild();\r
+                               if (!oc.getType().equals("child"))\r
+                                       continue;\r
+                               boolean match = false;\r
+                               if (element2 != null) {\r
+                                       if (parent.getType() == ObjectType.ELEMENT && parent.getName().equals(element2.getName())) {\r
+                                               match = true;\r
+                                       }\r
+                               } else if (complexType != null) {\r
+                                       if (parent.getType() == ObjectType.COMPLEX_TYPE && parent.getName() != null && parent.getName().equals(complexType.getName())) {\r
+                                               match = true;\r
+                                       }\r
+                                       \r
+                               }\r
+                               if (match) {\r
+                                       if (child != null) {\r
+                                               if (matchChild(child, refName, refType)) {\r
+                                                       if (oc.getValue().equals("disable"))\r
+                                                               return false;\r
+                                                       else return true;\r
+                                               }\r
+                                       } else {\r
+                                               if (oc.getValue().equals("disable"))\r
+                                                       return false;\r
+                                               return true;\r
+                                       }\r
+                                       \r
+                               }\r
+                       }\r
+               }\r
+               return element.many() && element.order();\r
+       }\r
+       \r
+       private boolean matchChild(org.simantics.xml.sax.configuration.Element child, String refName, QName refType) {\r
+               if (refType != null && refType.getLocalPart().equals(child.getName()))\r
+                       return true;\r
+               if (refName != null && refName.equals(child.getName()))\r
+                       return true;\r
+               return false;\r
+       }\r
+       \r
+       public static class TypeEntry {\r
+               String l0Type;\r
+               String binding;\r
+               String javaType;\r
+               String defaultValue;\r
+               boolean id;\r
+               public TypeEntry(String l0Type, String binding, String javaType, String defaultValue) {\r
+                       super();\r
+                       this.l0Type = l0Type;\r
+                       this.binding = binding;\r
+                       this.javaType = javaType;\r
+                       this.defaultValue = defaultValue;\r
+                       this.id = false;\r
+               }\r
+               \r
+               public TypeEntry(String l0Type, String binding, String javaType, String defaultValue, boolean id) {\r
+                       super();\r
+                       this.l0Type = l0Type;\r
+                       this.binding = binding;\r
+                       this.javaType = javaType;\r
+                       this.defaultValue = defaultValue;\r
+                       this.id = id;\r
+               }\r
+               \r
+       }\r
+\r
+}\r