]> gerrit.simantics Code Review - simantics/interop.git/blobdiff - org.simantics.xml.sax/src/org/simantics/xml/sax/SchemaConversionBase.java
Schema parsing can access data from other schemas (work in progress)
[simantics/interop.git] / org.simantics.xml.sax / src / org / simantics / xml / sax / SchemaConversionBase.java
index 5df8c4aefcbf4736d477410f4599c65c26286249..2bca88d64f5dfd666fee38f5d5cdf6a956fc4e84 100644 (file)
@@ -32,10 +32,12 @@ import org.w3._2001.xmlschema.ComplexType;
 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.GroupRef;\r
 import org.w3._2001.xmlschema.LocalElement;\r
 import org.w3._2001.xmlschema.NamedAttributeGroup;\r
+import org.w3._2001.xmlschema.NamedGroup;\r
 import org.w3._2001.xmlschema.OpenAttrs;\r
+import org.w3._2001.xmlschema.RealGroup;\r
 import org.w3._2001.xmlschema.Restriction;\r
 import org.w3._2001.xmlschema.Schema;\r
 import org.w3._2001.xmlschema.SimpleContent;\r
@@ -44,21 +46,34 @@ import org.w3._2001.xmlschema.TopLevelAttribute;
 import org.w3._2001.xmlschema.TopLevelComplexType;\r
 import org.w3._2001.xmlschema.TopLevelElement;\r
 import org.w3._2001.xmlschema.TopLevelSimpleType;\r
+import org.w3._2001.xmlschema.Union;\r
 \r
-public abstract class SchemaConversionBase {\r
+public final class SchemaConversionBase {\r
        \r
        protected Schema schema;\r
+       protected SchemaConverter converter;\r
+       protected SchemaConversionComponent component;\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
+       public static final String SCHEMA_NS = "http://www.w3.org/2001/XMLSchema";\r
+       public 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
+       protected String ontologyURI;\r
+       protected String className;\r
+       \r
+       public SchemaConversionBase(SchemaConverter converter, String ontologyUri, String className) {\r
+               this.converter = converter;\r
+               this.configuration = converter.getConfiguration();\r
+               this.ontologyURI = ontologyUri;\r
+               this.className = className;\r
                \r
+               initTypes();\r
+       }\r
+       \r
+       protected void initTypes() {\r
+               typeMap = new HashMap<String, Map<String,TypeEntry>>();\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
@@ -69,6 +84,8 @@ public abstract class SchemaConversionBase {
                schemaTypes.put("token",                new TypeEntry("L0.String",                      "Bindings.STRING", "java.lang.String", "","","","",""));\r
                schemaTypes.put("ID",                   new TypeEntry("L0.String",                      "Bindings.STRING", "java.lang.String", "","","","","",true));\r
                schemaTypes.put("IDREF",                new TypeEntry("L0.String",                      "Bindings.STRING", "java.lang.String", "","","","",""));\r
+               schemaTypes.put("Name",                 new TypeEntry("L0.String",                      "Bindings.STRING", "java.lang.String", "","","","",""));\r
+               schemaTypes.put("NCName",               new TypeEntry("L0.String",                      "Bindings.STRING", "java.lang.String", "","","","",""));\r
                schemaTypes.put("date",                 new TypeEntry("XML.Date",                       "org.simantics.xml.sax.base.datatypes.literal.Date.BINDING", "org.simantics.xml.sax.base.datatypes.literal.Date", "","org.simantics.xml.sax.base.datatypes.literal.Date.parseDate(",")","(",").toString()"));\r
                schemaTypes.put("time",                 new TypeEntry("XML.Time",                       "org.simantics.xml.sax.base.datatypes.literal.Time.BINDING", "org.simantics.xml.sax.base.datatypes.literal.Time", "","org.simantics.xml.sax.base.datatypes.literal.Time.parseTime(",")","(",").toString()"));\r
                schemaTypes.put("dateTime",             new TypeEntry("XML.DateTime",           "org.simantics.xml.sax.base.datatypes.literal.DateTime.BINDING", "org.simantics.xml.sax.base.datatypes.literal.DateTime", "","org.simantics.xml.sax.base.datatypes.literal.DateTime.parseDateTime(",")","(",").toString()"));\r
@@ -92,13 +109,10 @@ public abstract class SchemaConversionBase {
                schemaTypes.put("unsignedLong", new TypeEntry("L0.Long",                        "Bindings.LONG", "long", "0","java.lang.Long.parseLong(",")","java.lang.Long.toString(",")"));\r
                schemaTypes.put("base64Binary", new TypeEntry("L0.ByteArray",           "Bindings.BYTE_ARRAY", "byte[]", "new byte[0]","",".getBytes(org.simantics.databoard.util.binary.UTF8.CHARSET)","new java.lang.String(",", org.simantics.databoard.util.binary.UTF8.CHARSET)"));\r
                \r
-               \r
-               \r
                l0Types.put("doubleArray",              new TypeEntry("L0.DoubleArray",  "Bindings.DOUBLE_ARRAY", "double[]", null,null,null,"java.lang.Double.toString(",")"));\r
                l0Types.put("stringArray",              new TypeEntry("L0.StringArray",  "Bindings.STRING_ARRAY", "string[]", null,null,null,"",""));\r
        }\r
        \r
-       \r
        protected TypeEntry getTypeEntry(QName type) {\r
                Map<String,TypeEntry> types = typeMap.get(type.getNamespaceURI());\r
                if (types == null)\r
@@ -154,10 +168,14 @@ public abstract class SchemaConversionBase {
        }\r
        \r
        \r
-       protected void handle(Schema schema) {  \r
+       public void init(Schema schema) {       \r
                this.schema = schema;\r
-               preload();\r
                \r
+               preload();\r
+       }\r
+       \r
+       public void handle(SchemaConversionComponent component) {\r
+               this.component = component;\r
                for (OpenAttrs attrs : schema.getSimpleTypeOrComplexTypeOrGroup()) {\r
                        if (attrs instanceof TopLevelAttribute) {\r
                                handle((TopLevelAttribute)attrs);\r
@@ -170,33 +188,155 @@ public abstract class SchemaConversionBase {
                                handleSimpleType(simpleTypes.get(attrs));\r
                        } else if (attrs instanceof NamedAttributeGroup) {\r
                                handle((NamedAttributeGroup)attrs);\r
+                       } else if (attrs instanceof NamedGroup) {\r
+                               handle((NamedGroup)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
+       private Map<String,SchemaObject> elementName = new HashMap<>();\r
+       private Map<String,SchemaObject> complexTypeName = new HashMap<>();\r
+       private Map<String,SchemaObject> simpleTypeName = new HashMap<>();\r
+       private Map<String,SchemaObject> modelGroupName = new HashMap<>();\r
+       private Map<Element,SchemaObject> elements = new HashMap<>();\r
+       private Map<ComplexType,SchemaObject> complexTypes = new HashMap<>();\r
+       private Map<SimpleType,SchemaObject> simpleTypes = new HashMap<>();\r
+       private Map<NamedGroup,SchemaObject> modelGroups = new HashMap<>();\r
+       \r
+       private SchemaObject _getWithName(QName name) {\r
+               SchemaObject obj = elementName.get(name.getLocalPart());\r
                if (obj == null)\r
-                       obj = complexTypeName.get(name);\r
+                       obj = complexTypeName.get(name.getLocalPart());\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
+                       obj = simpleTypeName.get(name.getLocalPart());\r
                return obj;\r
        }\r
        \r
+       protected SchemaObject getWithName(QName name) {\r
+               SchemaObject obj = _getWithName(name);\r
+               if (obj != null)\r
+                       return obj;\r
+               if (name.getNamespaceURI() != null) {\r
+                       for (SchemaConverter sc : converter.getConverter(name.getNamespaceURI())) {\r
+                               if (sc.base != null) {\r
+                                       obj = sc.base._getWithName(name);\r
+                                       if (obj != null) {\r
+                                               return obj;\r
+                                       }\r
+                               }\r
+                       }               \r
+               }\r
+               return null;\r
+       }\r
+       \r
+       private NamedAttributeGroup _getAttributeGroup(QName name) {\r
+               for (OpenAttrs attrs : schema.getSimpleTypeOrComplexTypeOrGroup()) {\r
+                       if (attrs instanceof NamedAttributeGroup) {\r
+                               NamedAttributeGroup group = (NamedAttributeGroup)attrs;\r
+                               if (group.getName().equals(name.getLocalPart()))\r
+                                       return group;\r
+                       }\r
+               }\r
+               return null;\r
+       }\r
+\r
+       public NamedAttributeGroup getAttributeGroup(QName name) {\r
+               NamedAttributeGroup group = _getAttributeGroup(name);\r
+               if (group != null)\r
+                       return group;\r
+               if (name.getNamespaceURI() != null) {\r
+                       for (SchemaConverter sc : converter.getConverter(name.getNamespaceURI())) {\r
+                               if (sc.base != null) {\r
+                                       group = sc.base._getAttributeGroup(name);\r
+                                       if (group != null) {\r
+                                               return group;\r
+                                       }\r
+                               }\r
+                       }       \r
+               }\r
+               return null;\r
+       }\r
+       \r
+       private SchemaObject _getElement(QName name) {\r
+               return elementName.get(name.getLocalPart());\r
+       }\r
+       \r
+       protected SchemaObject getElement(QName name) {\r
+               SchemaObject obj = _getElement(name);\r
+               if (obj != null)\r
+                       return obj;\r
+               if (name.getNamespaceURI() != null) {\r
+                       for (SchemaConverter sc : converter.getConverter(name.getNamespaceURI())) {\r
+                               if (sc.base != null) {\r
+                                       obj = sc.base._getElement(name);\r
+                                       if (obj != null) {\r
+                                               return obj;\r
+                                       }\r
+                               }\r
+                       }               \r
+               }\r
+               return null;\r
+       }\r
+       \r
+       protected SchemaObject getElement(Element element) {\r
+               return elements.get(element);\r
+       }\r
+       \r
+       \r
+       private SchemaObject _getComplexType(QName name) {\r
+               return complexTypeName.get(name.getLocalPart());\r
+       }\r
+       \r
+       protected SchemaObject getComplexType(QName name) {\r
+               SchemaObject obj = _getComplexType(name);\r
+               if (obj != null)\r
+                       return obj;\r
+               if (name.getNamespaceURI() != null) {\r
+                       for (SchemaConverter sc : converter.getConverter(name.getNamespaceURI())) {\r
+                               if (sc.base != null) {\r
+                                       obj = sc.base._getComplexType(name);\r
+                                       if (obj != null) {\r
+                                               return obj;\r
+                                       }\r
+                               }\r
+                       }               \r
+               }\r
+               return null;\r
+       }\r
+       \r
+       protected SchemaObject getComplexType(ComplexType complexType) {\r
+               return complexTypes.get(complexType);\r
+       }\r
+       \r
+       private SchemaObject _getSimpleType(QName name) {\r
+               return simpleTypeName.get(name.getLocalPart());\r
+       }\r
+       \r
+       protected SchemaObject getSimpleType(QName name) {\r
+               SchemaObject obj = _getSimpleType(name);\r
+               if (obj != null)\r
+                       return obj;\r
+               if (name.getNamespaceURI() != null) {\r
+                       for (SchemaConverter sc : converter.getConverter(name.getNamespaceURI())) {\r
+                               if (sc.base != null) {\r
+                                       obj = sc.base._getSimpleType(name);\r
+                                       if (obj != null) {\r
+                                               return obj;\r
+                                       }\r
+                               }\r
+                       }               \r
+               }\r
+               return null;\r
+       }\r
+       \r
+       protected SchemaObject getSimpleType(SimpleType simpleType) {\r
+               return simpleTypes.get(simpleType);\r
+       }\r
+       \r
        protected SchemaObject getWithObj(SchemaObject referrer, OpenAttrs attrs) {\r
+               // FIXME : this method cannot handle references to other schemas.\r
                SchemaObject obj = null;\r
                if (attrs instanceof Element)\r
                        obj = elements.get(attrs);\r
@@ -228,12 +368,23 @@ public abstract class SchemaConversionBase {
                                SimpleType simpleType = (SimpleType)attrs;\r
                                SchemaObject obj = new SchemaObject(simpleType);\r
                                stack.push(obj);\r
+                       }  else if (attrs instanceof Attribute) {\r
+                               // Attributes are not cached\r
+                       } else if (attrs instanceof AttributeGroup) {\r
+                               // Attribute groups are not cached\r
+                       } else if (attrs instanceof NamedGroup) {\r
+                               NamedGroup group = (NamedGroup)attrs;\r
+                               SchemaObject obj = new SchemaObject(group);\r
+                               stack.push(obj);\r
+                       } else {\r
+                               System.out.println(attrs.getClass().getName());\r
                        }\r
                }\r
                \r
                while (!stack.isEmpty()) {\r
                        SchemaObject object = stack.pop();\r
-                       if (object.getType() == ObjectType.COMPLEX_TYPE) {\r
+                       switch (object.getType()) {\r
+                       case 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
@@ -283,7 +434,9 @@ public abstract class SchemaConversionBase {
                                                        throw new RuntimeException("Groups not supported");\r
                                        }\r
                                }\r
-                       } else if (object.getType() == ObjectType.ELEMENT) {\r
+                               break;\r
+                       } \r
+                       case ELEMENT:{\r
                                Element e = object.getElement();\r
                                if (e instanceof TopLevelElement)\r
                                        elementName.put(e.getName(), object);\r
@@ -292,13 +445,23 @@ public abstract class SchemaConversionBase {
                                        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
+                               break;\r
+                       } \r
+                       case SIMPLE_TYPE:{\r
                                SimpleType e = object.getSimpleType();\r
                                if (e instanceof TopLevelSimpleType)\r
                                        simpleTypeName.put(e.getName(), object);\r
                                simpleTypes.put(e, object);\r
+                               break;\r
+                       } \r
+                       case MODEL_GROUP:{\r
+                               NamedGroup e = object.getModelGroup();\r
+                               modelGroupName.put(e.getName(), object);\r
+                               modelGroups.put(e, object);\r
+                               break;\r
                        }\r
-               }\r
+                       }\r
+               } // while\r
        }\r
        \r
        private void preload(SchemaObject parent,ExplicitGroup eg, Deque<SchemaObject> stack) {\r
@@ -310,10 +473,10 @@ public abstract class SchemaConversionBase {
                                        SchemaObject obj = new SchemaObject(parent,(Element)elemValue);\r
                                        obj.setRename(getRename((Element)elemValue));\r
                                        stack.add(obj);\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 if (elemValue instanceof RealGroup) {\r
+                                       preload(parent,(RealGroup)elemValue, stack);\r
                                } else {\r
                                        throw new RuntimeException("Unknown ExplicitGroup element " + elemValue.getClass().getName());\r
                                }\r
@@ -325,6 +488,15 @@ public abstract class SchemaConversionBase {
                }\r
        }\r
        \r
+       private void preload(SchemaObject parent, RealGroup eg, Deque<SchemaObject> stack) {\r
+               System.out.println(eg); \r
+               if (eg instanceof NamedGroup) {\r
+                       SchemaObject obj = new SchemaObject(parent,(NamedGroup)eg);\r
+                       stack.add(obj);\r
+               }\r
+       }\r
+\r
+       \r
        protected void handle(TopLevelAttribute topLevelAttribute) {\r
                handle(null, topLevelAttribute);\r
        }\r
@@ -337,6 +509,10 @@ public abstract class SchemaConversionBase {
                handle(null, namedAttributeGroup);\r
        }\r
        \r
+       protected void handle(NamedGroup namedAttributeGroup){\r
+               handle(null, namedAttributeGroup);\r
+       }\r
+       \r
        protected QName getComplexTypeBase(ComplexType complexType) {\r
                if (complexType == null)\r
                        return null;\r
@@ -348,21 +524,67 @@ public abstract class SchemaConversionBase {
                                return type;\r
                        }\r
                }\r
-//             SimpleContent simpleContent = complexType.getSimpleContent();\r
-//             if (simpleContent != null) {\r
-//                     ExtensionType extensionType = simpleContent.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
+//             if (simpleType == null)\r
+//                     return null;\r
+//             return simpleType.getRestriction().getBase();\r
+               \r
+               Restriction restriction = simpleType.getRestriction();\r
+               if (restriction != null) {\r
+                       QName base = restriction.getBase();\r
+                       return base;\r
+               } else if (simpleType.getId() != null) {\r
+                       throw new RuntimeException(simpleType.getName() + " restriction error");\r
+               } else if (simpleType.getUnion() != null) {\r
+                       Union union = simpleType.getUnion();\r
+                       if (union.getMemberTypes().size() > 0) {\r
+                               QName base = null;\r
+                               for (QName type : union.getMemberTypes()) {\r
+                                       QName sType = null;\r
+                                       TypeEntry entry = getTypeEntry(type);\r
+                                       if (entry == null) {\r
+                                               SchemaObject obj = simpleTypeName.get(type.getLocalPart());\r
+                                               if (obj == null)\r
+                                                       throw new RuntimeException(simpleType.getName() + " union has unresolved reference " + type.getLocalPart());\r
+                                               sType = getSimpleTypeBase(obj.getSimpleType());\r
+                                       } else {\r
+                                               sType = type;\r
+                                       }\r
+                                       if (base == null)\r
+                                               base = sType;\r
+                                       else if (!base.equals(sType)) {\r
+                                               //FIXME : throw new RuntimeException(simpleType.getName() + " union has incompatible member types");\r
+                                               // fall back to string. \r
+                                               base = new QName(SCHEMA_NS, "string");\r
+                                               \r
+                                       }\r
+                               }\r
+                               return base;\r
+                       } else {\r
+                               if (union.getSimpleType().size() == 0)\r
+                                       throw new RuntimeException(simpleType.getName() + " union error");\r
+                               for (SimpleType s : union.getSimpleType()) {\r
+                                       if (restriction == null)\r
+                                               restriction = s.getRestriction();\r
+                                       else  {\r
+                                               Restriction r = s.getRestriction();\r
+                                               if (!r.getBase().equals(restriction.getBase()))\r
+                                                       throw new RuntimeException(simpleType.getName() + " union has incompatible restriction bases");\r
+                                       }\r
+                               }\r
+                               QName base = restriction.getBase();\r
+                               return base;\r
+                       }\r
+               } else if (simpleType.getList() != null) {\r
+                       // FIXME: callers cannot get the information that we have a list.\r
+                       org.w3._2001.xmlschema.List list = simpleType.getList();\r
+                       return list.getItemType();\r
+               } else {\r
+                       throw new RuntimeException(simpleType.getName() + " restriction error");\r
+               }\r
        }\r
        \r
        protected QName getElementBase(Element element) {\r
@@ -376,13 +598,6 @@ public abstract class SchemaConversionBase {
                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
@@ -401,7 +616,9 @@ public abstract class SchemaConversionBase {
                }\r
        }\r
        \r
-       protected abstract void handleAttributes(SchemaObject simpleTypeObj);\r
+       protected void handleAttributes(SchemaObject simpleTypeObj) {\r
+               component.handleAttributes(simpleTypeObj);\r
+       }\r
        \r
        protected void handleExtensionAttributes(SchemaObject complexType) {\r
                ComplexContent complexContent = complexType.getComplexType().getComplexContent();\r
@@ -511,22 +728,51 @@ public abstract class SchemaConversionBase {
                return null;\r
        }\r
        \r
-       protected abstract void handleAttributeComposition(SchemaObject obj, AttributeComposition composition, BijectionMap<org.simantics.xml.sax.configuration.Attribute, Annotated> attributes);\r
+       //protected abstract void handleAttributeComposition(SchemaObject obj, AttributeComposition composition, BijectionMap<org.simantics.xml.sax.configuration.Attribute, Annotated> attributes);\r
+       protected void handleAttributeComposition(SchemaObject obj, AttributeComposition composition, BijectionMap<org.simantics.xml.sax.configuration.Attribute, Annotated> attributes) {\r
+               component.handleAttributeComposition(obj, composition, attributes);\r
+       }\r
        \r
        \r
        \r
        \r
        protected void handleComplexType(SchemaObject complexType) {\r
-               handleComplexTypeAttributes(complexType);\r
-               handleComplexTypeExtension(complexType);\r
-               handleExtensionAttributes(complexType);\r
+//             handleComplexTypeAttributes(complexType);\r
+//             handleComplexTypeExtension(complexType);\r
+//             handleExtensionAttributes(complexType);\r
+               component.handleComplexType(complexType);\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
+               component.handleElement(topLevelElement);\r
        }\r
        \r
        protected enum RefType{Element,Reference,Type};\r
        \r
-       protected abstract void handleIndicator(SchemaObject parent, SchemaElement indicator, SchemaElement element, String refName, RefType refType);\r
-       protected abstract void handleIndicator(SchemaObject parent, SchemaElement indicator, SchemaElement any);\r
-       protected abstract void handle(SchemaObject parent, SchemaElement indicator, List<SchemaElement> elements);\r
+       protected void handleIndicator(SchemaObject parent, SchemaElement indicator, SchemaElement element, String refName, RefType refType) {\r
+               component.handleIndicator(parent, indicator, element, refName, refType);\r
+       }\r
+       protected void handleIndicator(SchemaObject parent, SchemaElement indicator, SchemaElement any) {\r
+               component.handleIndicator(parent, indicator, any);\r
+       }\r
+       protected void handle(SchemaObject parent, SchemaElement indicator, List<SchemaElement> elements) {\r
+               //component.handle(parent, indicator, elements);\r
+               if (indicator.getType() == SchemaElement.ElementType.SEQUENCE || (indicator.getType() == SchemaElement.ElementType.CHOICE && indicator.getRestriction().many())) {\r
+                       for (SchemaElement e : elements) {\r
+                               handle(parent, indicator, e);\r
+                       }\r
+               } else if (indicator.getType() == SchemaElement.ElementType.CHOICE) {\r
+                       String name = getChoiceName(elements);\r
+                       component.handleChoice(parent, indicator, elements, name);\r
+               }\r
+       }\r
        \r
        protected void handle(SchemaObject parent, ExplicitGroup eg, SchemaElement.ElementType indicator) {\r
                handle(parent, new SchemaElement(eg, indicator));\r
@@ -540,6 +786,7 @@ public abstract class SchemaConversionBase {
                List<SchemaElement> sequences = new ArrayList<SchemaElement>();\r
                List<SchemaElement> alls = new ArrayList<SchemaElement>();\r
                List<SchemaElement> anys = new ArrayList<SchemaElement>();\r
+               List<SchemaElement> groups = new ArrayList<SchemaElement>();\r
                \r
                for (Object o : indicator.getGroup().getParticle()) {\r
                        if (o instanceof JAXBElement<?>) {\r
@@ -557,6 +804,14 @@ public abstract class SchemaConversionBase {
                                        } else if ("sequence".equals(qname.getLocalPart())) {\r
                                                sequences.add(new SchemaElement(indicator,(ExplicitGroup)elemValue, ElementType.SEQUENCE));\r
                                        }\r
+                               } else if (elemValue instanceof RealGroup) {\r
+                                       if (elemValue instanceof GroupRef) {\r
+                                               groups.add(new SchemaElement(indicator,(GroupRef)elemValue, ElementType.GROUP_REF));\r
+                                       } else if (elemValue instanceof NamedGroup) {\r
+                                               groups.add(new SchemaElement(indicator,(NamedGroup)elemValue, ElementType.NAMED_GROUP));\r
+                                       } else {\r
+                                               throw new RuntimeException("Unknown ExplicitGroup element " + elemValue.getClass().getName());\r
+                                       }\r
                                } else {\r
                                        throw new RuntimeException("Unknown ExplicitGroup element " + elemValue.getClass().getName());\r
                                }\r
@@ -567,7 +822,7 @@ public abstract class SchemaConversionBase {
                        }\r
                }\r
                \r
-               if (elements.size() == 0 && choices.size() == 0 && sequences.size() == 0 && alls.size() == 0 && anys.size() == 0) {\r
+               if (elements.size() == 0 && choices.size() == 0 && sequences.size() == 0 && alls.size() == 0 && anys.size() == 0 && groups.size() == 0) {\r
                        return;\r
                }\r
                \r
@@ -584,6 +839,10 @@ public abstract class SchemaConversionBase {
                                        for (SchemaElement c : alls) {\r
                                                handle(parent, c);\r
                                        }\r
+                                       \r
+                                       for (SchemaElement c : groups) {\r
+                                               handle(parent, c);\r
+                                       }\r
                                        handle(parent, indicator, elements);\r
                                        for (SchemaElement a : anys) {\r
                                                handleIndicator(parent, indicator, a);\r
@@ -598,9 +857,23 @@ public abstract class SchemaConversionBase {
                                        for (SchemaElement a : anys) {\r
                                                handleIndicator(parent, indicator, a);\r
                                        }\r
+                                       for (SchemaElement c : groups) {\r
+                                               handle(parent, c);\r
+                                       }\r
                                }\r
                        } else {\r
-                               if (sequences.size() > 0 || choices.size() > 0 || alls.size() > 0) {\r
+                               if (choices.size() == 1 && sequences.size() == 0 && alls.size() == 0 && groups.size() == 0) {\r
+                                       // special case: handle lone choice inside sequence with maxOccurs > 1 \r
+                                       SchemaElement choice = choices.get(0);\r
+                                       // move multiplicity restrictions to choice\r
+                                       if (indicator.getRestriction().max == -1 || (choice.getRestriction().max > 0 && indicator.getRestriction().max > choice.getRestriction().max))\r
+                                               choice.getRestriction().max = indicator.getRestriction().max;\r
+                                       if (indicator.getRestriction().min == 0 || choice.getRestriction().min > indicator.getRestriction().min)\r
+                                               choice.getRestriction().min = indicator.getRestriction().min;\r
+                                       handle(parent, choice, elements);\r
+                                       return;\r
+                               }\r
+                               if (sequences.size() > 0 || choices.size() > 0 || alls.size() > 0 || groups.size() > 0) {\r
                                        throw new RuntimeException("Cannot handle Sequence with inner ExplicitGroups");\r
                                }\r
                                handle(parent, indicator, elements);\r
@@ -611,13 +884,13 @@ public abstract class SchemaConversionBase {
                \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
+                               if (sequences.size()> 0 || choices.size() > 0 || alls.size() > 0 || anys.size() > 0 || groups.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
+                               if (sequences.size() > 0 || choices.size() > 0 || alls.size() > 0 || groups.size() > 0) {\r
                                        throw new RuntimeException("Cannot handle Choice with inner ExplicitGroups");\r
                                }\r
                                handle(parent, indicator,  elements);\r
@@ -626,7 +899,7 @@ public abstract class SchemaConversionBase {
                                }\r
                        }\r
                } else if (indicator.getType() == ElementType.ALL) {\r
-                       if (sequences.size()> 0 || choices.size() > 0 || alls.size() > 0 || anys.size() > 0) {\r
+                       if (sequences.size()> 0 || choices.size() > 0 || alls.size() > 0 || anys.size() > 0  || groups.size() > 0) {\r
                                throw new RuntimeException("Cannot handle All that contains something else than Elements");\r
                        }\r
                        if (!indicator.getRestriction().single()) {\r
@@ -640,20 +913,15 @@ public abstract class SchemaConversionBase {
        protected void handle(SchemaObject parent, SchemaElement indicator, SchemaElement element) {\r
                Element localElement = element.getElement();\r
                if (localElement.getName() != null) {\r
-                       SchemaObject eObj = elements.get(localElement); // FIXME: handleIndicator should be refactored, not this methdof must be overridden in JavaGenerator to handle renaming of Elements properly\r
-                       //String refName = eObj.getName();//localElement.getName();\r
+                       SchemaObject eObj = elements.get(localElement); \r
                        QName refType = localElement.getType();\r
                        if (refType != null)\r
-                               //handleIndicator(parent, indicator, element, false, refName, refType);\r
                                handleIndicator(parent, indicator, element, null, RefType.Type);\r
                        else {\r
                                handleElement(eObj);\r
-                               //handleIndicator(parent, indicator, element, false, refName, localElement);\r
                                handleIndicator(parent, indicator, element, null, RefType.Element);\r
                        }\r
                } else if (localElement.getRef() != null) {\r
-                       //QName refType = localElement.getRef();\r
-                       //handleIndicator(parent, indicator,element, true, refType.getLocalPart(), refType);\r
                        handleIndicator(parent, indicator,element, null, RefType.Reference);\r
                }\r
        }\r
@@ -691,12 +959,20 @@ public abstract class SchemaConversionBase {
                }\r
                return name;\r
        }\r
+               \r
+       protected void handle(SchemaObject parent, Attribute attribute) {\r
+               component.handle(parent, attribute);\r
+       }\r
+       protected void handle(SchemaObject parent, AttributeGroup attribute) {\r
+               component.handle(parent, attribute);\r
+       }\r
+       protected void handle(SchemaObject parent, NamedGroup attribute){\r
+               component.handle(parent, attribute);\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
+       protected void handleSimpleType(SchemaObject parent, SchemaObject simpleType) {\r
+               component.handleSimpleType(parent, simpleType);\r
+       }\r
        \r
        \r
        \r
@@ -736,43 +1012,20 @@ public abstract class SchemaConversionBase {
                }\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
+       public boolean isElementRef(String ref) {\r
                return elementName.containsKey(ref);\r
        }\r
        \r
-       protected boolean isComplexTypeRef(String ref) {\r
+       public boolean isComplexTypeRef(String ref) {\r
                return complexTypeName.containsKey(ref);\r
        }\r
        \r
-       protected boolean isSimpleTypeRef(String ref) {\r
+       public boolean isSimpleTypeRef(String ref) {\r
                return simpleTypeName.containsKey(ref);\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
+       public 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
@@ -792,7 +1045,7 @@ public abstract class SchemaConversionBase {
                return idProviders.get(0);\r
        }\r
        \r
-       protected IDProvider getIDProvider(ComplexType complexType) {\r
+       public 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
@@ -812,7 +1065,7 @@ public abstract class SchemaConversionBase {
                return idProviders.get(0);\r
        }\r
        \r
-       protected List<IDReference> getIDReferences(Element element) {\r
+       public 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
@@ -827,7 +1080,7 @@ public abstract class SchemaConversionBase {
                return idReferences;\r
        }\r
        \r
-       protected List<IDReference> getIDReferences(ComplexType complexType) {\r
+       public 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
@@ -1069,5 +1322,145 @@ public abstract class SchemaConversionBase {
                }\r
                \r
        }\r
+       \r
+       public enum InheritanceType{ComplexType,AtomicType,None};\r
+       \r
+       public static class Inheritance {\r
+               public String baseClass;\r
+               public InheritanceType type;\r
+               public TypeEntry atomicType;\r
+               \r
+               public Inheritance(String baseClass) {\r
+                       this.baseClass = baseClass;\r
+                       this.type = InheritanceType.None;\r
+               }\r
+       }\r
+       \r
+       public String getComplexTypePrefix() {\r
+               return component.getComplexTypePrefix();\r
+       }\r
+       public String getAttributeGroupPrefix() {\r
+               return component.getAttributeGroupPrefix();\r
+       }\r
+       public String getName(SchemaObject obj) {\r
+               return component.getName(obj);\r
+       }\r
+       public String getBaseClass(ObjectType type) {\r
+               return component.getBaseClass(type);\r
+       }\r
+       \r
+       \r
+       \r
+       public Inheritance getInheritance(SchemaObject topLevelObj) {\r
+               Inheritance inheritance = null;\r
+               if (topLevelObj.getType() == ObjectType.ELEMENT) {\r
+                       Element topLevelElement = topLevelObj.getElement();\r
+                       inheritance = new Inheritance(getBaseClass(ObjectType.ELEMENT));\r
+                       if (topLevelElement.getType() != null) {\r
+                               QName type = topLevelElement.getType();\r
+                               if (!type.getNamespaceURI().equals(SCHEMA_NS)) {\r
+                                       SchemaObject obj = complexTypeName.get(type.getLocalPart());\r
+       //                              if (obj == null)\r
+       //                                      obj = simpleTypeName.get(type.getLocalPart());\r
+                                       if (obj != null) {\r
+                                               inheritance.baseClass = getName(obj);\r
+                                               inheritance.type = InheritanceType.ComplexType;\r
+                                       }\r
+                               } else {\r
+                                       TypeEntry entry = getTypeEntry(type);\r
+                                       if (entry != null) {\r
+                                               inheritance.type = InheritanceType.AtomicType;\r
+                                               inheritance.atomicType = entry;\r
+                                       }\r
+                               }\r
+                       }\r
+                       if (inheritance.type == InheritanceType.None) {\r
+                               QName type = getElementBase(topLevelElement);\r
+                               if (type != null) {\r
+                                       if (!type.getNamespaceURI().equals(SCHEMA_NS)) {\r
+                                               SchemaObject obj = getWithName(type);\r
+                                               inheritance.baseClass = getName(obj);\r
+                                               inheritance.type = InheritanceType.ComplexType;\r
+                                       } else {\r
+                                               TypeEntry entry = getTypeEntry(type);\r
+                                               if (entry != null) {\r
+                                                       inheritance.type = InheritanceType.AtomicType;\r
+                                                       inheritance.atomicType = entry;\r
+                                               }\r
+                                       }\r
+                               }\r
+                       }\r
+                       if (inheritance.type == InheritanceType.None) {\r
+                               QName type = topLevelElement.getSubstitutionGroup();\r
+                               if (type != null) {\r
+                                       if (!type.getNamespaceURI().equals(SCHEMA_NS)) {\r
+                                               SchemaObject obj = getWithName(type);\r
+                                               inheritance.baseClass = getName(obj);\r
+                                               inheritance.type = InheritanceType.ComplexType;\r
+                                       } else {\r
+                                               TypeEntry entry = getTypeEntry(type);\r
+                                               if (entry != null) {\r
+                                                       inheritance.type = InheritanceType.AtomicType;\r
+                                                       inheritance.atomicType = entry;\r
+                                               }\r
+                                       }\r
+                               }\r
+                       }\r
+               } else if (topLevelObj.getType() == ObjectType.COMPLEX_TYPE) {\r
+                       ComplexType complexType = topLevelObj.getComplexType();\r
+                       QName type = getComplexTypeBase(complexType);\r
+                       inheritance = new Inheritance(getBaseClass(ObjectType.COMPLEX_TYPE));\r
+                       if (type != null && !type.getNamespaceURI().equals("http://www.w3.org/2001/XMLSchema")) {\r
+                               SchemaObject obj = complexTypeName.get(type.getLocalPart());\r
+                               if (obj != null) {\r
+                                       inheritance.baseClass = getName(obj);\r
+                                       inheritance.type = InheritanceType.ComplexType;\r
+                               }\r
+                       }\r
+                       SimpleContent simpleContent = complexType.getSimpleContent();\r
+                       if (simpleContent != null) {\r
+                               ExtensionType extensionType = simpleContent.getExtension();\r
+                               if (extensionType != null) {\r
+                                       type = extensionType.getBase();\r
+                                       getAtomicTypeInheritance(type, inheritance);\r
+                               }\r
+                       }\r
+               }\r
+               \r
+               return inheritance;\r
+       }       \r
+       /**\r
+        * Goes through chain of SimpleTypes until locates Atomic Type (type defined in XML schema). \r
+        * @param type\r
+        * @param topLevelObj\r
+        * @param inheritance\r
+        */\r
+       public void getAtomicTypeInheritance(QName type, Inheritance inheritance) {\r
+               if (!type.getNamespaceURI().equals(SCHEMA_NS)) {\r
+                       SchemaObject obj = getWithName(type);\r
+                       System.out.println();\r
+                       if (obj.getType() != ObjectType.SIMPLE_TYPE)\r
+                               throw new RuntimeException("SimpleContent does not use SimpleType definition");\r
+                       SimpleType simpleType = obj.getSimpleType();\r
+                       type = getSimpleTypeBase(simpleType);\r
+                       getAtomicTypeInheritance(type, inheritance);\r
+               } else {\r
+                       TypeEntry entry = getTypeEntry(type);\r
+                       if (entry != null) {\r
+                               inheritance.type = InheritanceType.AtomicType;\r
+                               inheritance.atomicType = entry;\r
+                       }\r
+               }\r
+       }\r
+       \r
+       public String getDefaultValue(QName atype) {\r
+               Map<String,TypeEntry> types = typeMap.get(atype.getNamespaceURI());\r
+               if (types == null)\r
+                       return null;\r
+               TypeEntry entry =  types.get(atype.getLocalPart());\r
+               if (entry == null)\r
+                       return null;\r
+               return entry.defaultValue;\r
+       }\r
 \r
 }\r