]> gerrit.simantics Code Review - simantics/interop.git/blobdiff - org.simantics.xml.sax/src/org/simantics/xml/sax/SchemaConversionBase.java
Refactoring and preparing the conversion code to handle references between XML schemas.
[simantics/interop.git] / org.simantics.xml.sax / src / org / simantics / xml / sax / SchemaConversionBase.java
index bcff6982821b680ebf230e9c4840c5a30dea5901..3e6c8818732a102cd5b56601e1847eaeff2963be 100644 (file)
@@ -2,7 +2,6 @@ package org.simantics.xml.sax;
 \r
 import java.util.ArrayDeque;\r
 import java.util.ArrayList;\r
-import java.util.Base64;\r
 import java.util.Deque;\r
 import java.util.HashMap;\r
 import java.util.HashSet;\r
@@ -21,6 +20,7 @@ import org.simantics.xml.sax.configuration.Configuration;
 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.Rename;\r
 import org.simantics.xml.sax.configuration.UnrecognizedChildElement;\r
 import org.w3._2001.xmlschema.All;\r
 import org.w3._2001.xmlschema.Annotated;\r
@@ -32,72 +32,87 @@ 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
 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
+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
                typeMap.put(CONVERSION_NS, l0Types);\r
                \r
-               schemaTypes.put("string",               new TypeEntry("L0.String",                      "Bindings.STRING", "java.lang.String", "","",""));\r
-               schemaTypes.put("NMTOKEN",              new TypeEntry("L0.String",                      "Bindings.STRING", "java.lang.String", "","",""));\r
-               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("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(",")"));\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(",")"));\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(",")"));\r
-               schemaTypes.put("anyURI",               new TypeEntry("L0.URI",                         "Bindings.STRING", "java.lang.String", "","",""));\r
-               schemaTypes.put("double",               new TypeEntry("L0.Double",                      "Bindings.DOUBLE", "double", "java.lang.Double.NaN","java.lang.Double.parseDouble(",")"));\r
-               schemaTypes.put("float",                new TypeEntry("L0.Float",                       "Bindings.FLOAT",  "float",  "java.lang.Float.NaN","java.lang.Float.parseFloat(",")"));\r
-               schemaTypes.put("decimal",              new TypeEntry("L0.Double",                      "Bindings.DOUBLE", "double", "java.lang.Double.NaN","java.lang.Double.parseDouble(",")"));\r
-               schemaTypes.put("boolean",              new TypeEntry("L0.Boolean",                     "Bindings.BOOLEAN", "boolean", "false","java.lang.Boolean.parseBoolean(",")"));\r
-               schemaTypes.put("integer",              new TypeEntry("L0.Integer",             "Bindings.INTEGER", "int", "0","java.lang.Integer.parseInt(",")"));\r
-               schemaTypes.put("positiveInteger", new TypeEntry("L0.Integer",          "Bindings.INTEGER", "int", "0","java.lang.Integer.parseInt(",")"));\r
-               schemaTypes.put("nonPositiveInteger", new TypeEntry("L0.Integer",       "Bindings.INTEGER", "int", "0","java.lang.Integer.parseInt(",")"));\r
-               schemaTypes.put("nonNegativeInteger", new TypeEntry("L0.Integer",       "Bindings.INTEGER", "int", "0","java.lang.Integer.parseInt(",")"));\r
-               schemaTypes.put("negativeInteger", new TypeEntry("L0.Integer",          "Bindings.INTEGER", "int", "0","java.lang.Integer.parseInt(",")"));\r
-               schemaTypes.put("unsignedInt",  new TypeEntry("L0.Integer",             "Bindings.INTEGER", "int", "0","java.lang.Integer.parseInt(",")"));\r
-               schemaTypes.put("int",                  new TypeEntry("L0.Integer",                     "Bindings.INTEGER", "int", "0","java.lang.Integer.parseInt(",")"));\r
-               schemaTypes.put("short",                new TypeEntry("L0.Integer",                     "Bindings.INTEGER", "int", "0","java.lang.Integer.parseInt(",")"));\r
-               schemaTypes.put("unsignedShort",new TypeEntry("L0.Integer",                     "Bindings.INTEGER", "int", "0","java.lang.Integer.parseInt(",")"));\r
-               schemaTypes.put("byte",                 new TypeEntry("L0.Byte",                        "Bindings.BYTE", "byte", "0","java.lang.Byte.parseByte(",")"));\r
-               schemaTypes.put("unsignedByte", new TypeEntry("L0.Byte",                        "Bindings.BYTE", "byte", "0","java.lang.Byte.parseByte(",")"));\r
-               schemaTypes.put("long",                 new TypeEntry("L0.Long",                        "Bindings.LONG", "long", "0","java.lang.Long.parseLong(",")"));\r
-               schemaTypes.put("unsignedLong", new TypeEntry("L0.Long",                        "Bindings.LONG", "long", "0","java.lang.Long.parseLong(",")"));\r
-               schemaTypes.put("base64Binary", new TypeEntry("L0.ByteArray",           "Bindings.BYTE_ARRAY", "byte[]", "new byte[0]","",".getBytes(org.simantics.databoard.util.binary.UTF8.CHARSET)"));\r
-               \r
+               schemaTypes.put("string",               new TypeEntry("L0.String",                      "Bindings.STRING", "java.lang.String", "","","","",""));\r
+               schemaTypes.put("NMTOKEN",              new TypeEntry("L0.String",                      "Bindings.STRING", "java.lang.String", "","","","",""));\r
+               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
+               schemaTypes.put("anyURI",               new TypeEntry("L0.URI",                         "Bindings.STRING", "java.lang.String", "","","","",""));\r
+               schemaTypes.put("double",               new TypeEntry("L0.Double",                      "Bindings.DOUBLE", "double", "java.lang.Double.NaN","java.lang.Double.parseDouble(",")","java.lang.Double.toString(",")"));\r
+               schemaTypes.put("float",                new TypeEntry("L0.Float",                       "Bindings.FLOAT",  "float",  "java.lang.Float.NaN","java.lang.Float.parseFloat(",")","java.lang.Float.toString(",")"));\r
+               schemaTypes.put("decimal",              new TypeEntry("L0.Double",                      "Bindings.DOUBLE", "double", "java.lang.Double.NaN","java.lang.Double.parseDouble(",")","java.lang.Double.toString(",")"));\r
+               schemaTypes.put("boolean",              new TypeEntry("L0.Boolean",                     "Bindings.BOOLEAN", "boolean", "false","java.lang.Boolean.parseBoolean(",")","java.lang.Boolean.toString(",")"));\r
+               schemaTypes.put("integer",              new TypeEntry("L0.Integer",             "Bindings.INTEGER", "int", "0","java.lang.Integer.parseInt(",")","java.lang.Integer.toString(",")"));\r
+               schemaTypes.put("positiveInteger", new TypeEntry("L0.Integer",          "Bindings.INTEGER", "int", "0","java.lang.Integer.parseInt(",")","java.lang.Integer.toString(",")"));\r
+               schemaTypes.put("nonPositiveInteger", new TypeEntry("L0.Integer",       "Bindings.INTEGER", "int", "0","java.lang.Integer.parseInt(",")","java.lang.Integer.toString(",")"));\r
+               schemaTypes.put("nonNegativeInteger", new TypeEntry("L0.Integer",       "Bindings.INTEGER", "int", "0","java.lang.Integer.parseInt(",")","java.lang.Integer.toString(",")"));\r
+               schemaTypes.put("negativeInteger", new TypeEntry("L0.Integer",          "Bindings.INTEGER", "int", "0","java.lang.Integer.parseInt(",")","java.lang.Integer.toString(",")"));\r
+               schemaTypes.put("unsignedInt",  new TypeEntry("L0.Integer",             "Bindings.INTEGER", "int", "0","java.lang.Integer.parseInt(",")","java.lang.Integer.toString(",")"));\r
+               schemaTypes.put("int",                  new TypeEntry("L0.Integer",                     "Bindings.INTEGER", "int", "0","java.lang.Integer.parseInt(",")","java.lang.Integer.toString(",")"));\r
+               schemaTypes.put("short",                new TypeEntry("L0.Integer",                     "Bindings.INTEGER", "int", "0","java.lang.Integer.parseInt(",")","java.lang.Integer.toString(",")"));\r
+               schemaTypes.put("unsignedShort",new TypeEntry("L0.Integer",                     "Bindings.INTEGER", "int", "0","java.lang.Integer.parseInt(",")","java.lang.Integer.toString(",")"));\r
+               schemaTypes.put("byte",                 new TypeEntry("L0.Byte",                        "Bindings.BYTE", "byte", "0","java.lang.Byte.parseByte(",")","java.lang.Byte.toString(",")"));\r
+               schemaTypes.put("unsignedByte", new TypeEntry("L0.Byte",                        "Bindings.BYTE", "byte", "0","java.lang.Byte.parseByte(",")","java.lang.Byte.toString(",")"));\r
+               schemaTypes.put("long",                 new TypeEntry("L0.Long",                        "Bindings.LONG", "long", "0","java.lang.Long.parseLong(",")","java.lang.Long.toString(",")"));\r
+               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
-               l0Types.put("doubleArray",              new TypeEntry("L0.DoubleArray",  "Bindings.DOUBLE_ARRAY", "double[]", null,null,null));\r
-               l0Types.put("stringArray",              new TypeEntry("L0.StringArray",  "Bindings.STRING_ARRAY", "string[]", null,null,null));\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
@@ -153,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
@@ -169,18 +188,22 @@ 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
+       protected Map<String,SchemaObject> elementName = new HashMap<>();\r
+       protected Map<String,SchemaObject> complexTypeName = new HashMap<>();\r
+       protected Map<String,SchemaObject> simpleTypeName = new HashMap<>();\r
+       protected Map<String,SchemaObject> modelGroupName = new HashMap<>();\r
+       protected Map<Element,SchemaObject> elements = new HashMap<>();\r
+       protected Map<ComplexType,SchemaObject> complexTypes = new HashMap<>();\r
+       protected Map<SimpleType,SchemaObject> simpleTypes = new HashMap<>();\r
+       protected Map<NamedGroup,SchemaObject> modelGroups = new HashMap<>();\r
        \r
        \r
        protected SchemaObject getWithName(SchemaObject referrer, String name) {\r
@@ -195,6 +218,18 @@ public abstract class SchemaConversionBase {
                return obj;\r
        }\r
        \r
+       protected SchemaObject getWithName(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);\r
+               }\r
+               return obj;\r
+       }\r
+       \r
        protected SchemaObject getWithObj(SchemaObject referrer, OpenAttrs attrs) {\r
                SchemaObject obj = null;\r
                if (attrs instanceof Element)\r
@@ -216,21 +251,34 @@ public abstract class SchemaConversionBase {
                        if (attrs instanceof Element) {\r
                                Element element = (Element)attrs;\r
                                SchemaObject obj = new SchemaObject(element);\r
+                               obj.setRename(getRename(element));\r
                                stack.push(obj);\r
                        } else if (attrs instanceof ComplexType) {\r
                                ComplexType complexType = (ComplexType)attrs;\r
                                SchemaObject obj = new SchemaObject(complexType);\r
+                               obj.setRename(getRename(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
+                       }  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
@@ -263,7 +311,26 @@ public abstract class SchemaConversionBase {
                                                        throw new RuntimeException("Groups not supported");\r
                                        }\r
                                }\r
-                       } else if (object.getType() == ObjectType.ELEMENT) {\r
+                               if (ct.getSimpleContent() != null) {\r
+                                       SimpleContent cc = ct.getSimpleContent();\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
+                               break;\r
+                       } \r
+                       case ELEMENT:{\r
                                Element e = object.getElement();\r
                                if (e instanceof TopLevelElement)\r
                                        elementName.put(e.getName(), object);\r
@@ -272,13 +339,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
@@ -287,11 +364,13 @@ public abstract class SchemaConversionBase {
                                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
+                                       SchemaObject obj = new SchemaObject(parent,(Element)elemValue);\r
+                                       obj.setRename(getRename((Element)elemValue));\r
+                                       stack.add(obj);\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
@@ -303,6 +382,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
@@ -315,6 +403,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
@@ -330,9 +422,63 @@ public abstract class SchemaConversionBase {
        }\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
@@ -371,7 +517,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
@@ -381,6 +529,13 @@ public abstract class SchemaConversionBase {
                                handleAttributes(complexType, extensionType.getAttributeOrAttributeGroup());\r
                        }\r
                }\r
+               SimpleContent simpleContent = complexType.getComplexType().getSimpleContent();\r
+               if (simpleContent != null) {\r
+                       ExtensionType extensionType = simpleContent.getExtension();\r
+                       if (extensionType != null) {\r
+                               handleAttributes(complexType, extensionType.getAttributeOrAttributeGroup());\r
+                       }\r
+               }\r
        }\r
        \r
        \r
@@ -474,21 +629,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 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
+       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 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
@@ -502,6 +687,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
@@ -509,7 +695,6 @@ public abstract class SchemaConversionBase {
                                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
@@ -520,6 +705,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
@@ -530,7 +723,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
@@ -547,6 +740,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
@@ -561,9 +758,12 @@ 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 (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
@@ -574,13 +774,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
@@ -589,7 +789,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
@@ -603,18 +803,16 @@ public abstract class SchemaConversionBase {
        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
+                       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(elements.get(localElement));\r
-                               handleIndicator(parent, indicator, element, false, refName, localElement);\r
-                               //FIXME:\r
+                               handleElement(eObj);\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
        \r
@@ -651,12 +849,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
@@ -689,48 +895,27 @@ public abstract class SchemaConversionBase {
                                        }\r
                                }\r
                        }\r
+//                     SimpleContent simpleContent = complexType.getSimpleContent();\r
+//                     if (simpleContent != null) {\r
+//                             ExtensionType extensionType = simpleContent.getExtension();\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
+       public boolean isElementRef(String ref) {\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
+       public boolean isComplexTypeRef(String ref) {\r
                return complexTypeName.containsKey(ref);\r
-               \r
        }\r
        \r
-       protected NamedAttributeGroup getAttributeGroup(String name) {\r
+       public boolean isSimpleTypeRef(String ref) {\r
+               return simpleTypeName.containsKey(ref);\r
+       }\r
+       \r
+       public NamedAttributeGroup getAttributeGroup(String name) {\r
                for (OpenAttrs attrs : schema.getSimpleTypeOrComplexTypeOrGroup()) {\r
                        if (attrs instanceof NamedAttributeGroup) {\r
                                NamedAttributeGroup group = (NamedAttributeGroup)attrs;\r
@@ -741,7 +926,7 @@ public abstract class SchemaConversionBase {
                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
@@ -761,7 +946,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
@@ -781,7 +966,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
@@ -796,7 +981,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
@@ -814,11 +999,11 @@ public abstract class SchemaConversionBase {
        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
+                               UnrecognizedChildElement rule = (UnrecognizedChildElement)e.getValue();\r
+                               org.simantics.xml.sax.configuration.ComplexType complexType2 = rule.getComplexType();\r
                                if (complexType2 != null) {\r
                                        if (complexType.getName().equals(complexType2.getName()))\r
-                                               return ref;\r
+                                               return rule;\r
                                }\r
                        }\r
                }\r
@@ -828,17 +1013,65 @@ public abstract class SchemaConversionBase {
        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
+                               UnrecognizedChildElement rule = (UnrecognizedChildElement)e.getValue();\r
+                               org.simantics.xml.sax.configuration.Element element2 = rule.getElement();\r
                                if (element2 != null) {\r
                                        if (element.getName().equals(element2.getName()))\r
-                                               return ref;\r
+                                               return rule;\r
                                }\r
                        }\r
                }\r
                return null;\r
        }\r
        \r
+       public Rename getRename(Attribute element) {\r
+               for (JAXBElement<?> e : configuration.getConversionRule()) {\r
+                       if (e.getValue() instanceof Rename) {\r
+                               Rename rule = (Rename)e.getValue();\r
+                               Object ref = rule.getElementOrComplexTypeOrAttribute().get(0);\r
+                               if (!(ref instanceof org.simantics.xml.sax.configuration.Attribute))\r
+                                       continue;\r
+                               org.simantics.xml.sax.configuration.Attribute element2 = (org.simantics.xml.sax.configuration.Attribute)ref;\r
+                               if (element2.getName().equals(element.getName())) {\r
+                                       return rule;\r
+                               }\r
+                       }\r
+               }\r
+               return null;\r
+       }\r
+       \r
+       public Rename getRename(ComplexType element) {\r
+               for (JAXBElement<?> e : configuration.getConversionRule()) {\r
+                       if (e.getValue() instanceof Rename) {\r
+                               Rename rule = (Rename)e.getValue();\r
+                               Object ref = rule.getElementOrComplexTypeOrAttribute().get(0);\r
+                               if (!(ref instanceof org.simantics.xml.sax.configuration.ComplexType))\r
+                                       continue;\r
+                               org.simantics.xml.sax.configuration.ComplexType element2 = (org.simantics.xml.sax.configuration.ComplexType)ref;\r
+                               if (element2.getName().equals(element.getName())) {\r
+                                       return rule;\r
+                               }\r
+                       }\r
+               }\r
+               return null;\r
+       }\r
+       \r
+       public Rename getRename(Element element) {\r
+               for (JAXBElement<?> e : configuration.getConversionRule()) {\r
+                       if (e.getValue() instanceof Rename) {\r
+                               Rename rule = (Rename)e.getValue();\r
+                               Object ref = rule.getElementOrComplexTypeOrAttribute().get(0);\r
+                               if (!(ref instanceof org.simantics.xml.sax.configuration.Element))\r
+                                       continue;\r
+                               org.simantics.xml.sax.configuration.Element element2 = (org.simantics.xml.sax.configuration.Element)ref;\r
+                               if (element2.getName().equals(element.getName())) {\r
+                                       return rule;\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
@@ -942,7 +1175,9 @@ public abstract class SchemaConversionBase {
                boolean id;\r
                String getterPrefix;\r
                String getterPostfix;\r
-               public TypeEntry(String l0Type, String binding, String javaType, String defaultValue, String getterPrefix, String getterPostfix) {\r
+               String stringPrefix;\r
+               String stringPostfix;\r
+               public TypeEntry(String l0Type, String binding, String javaType, String defaultValue, String getterPrefix, String getterPostfix, String stringPrefix, String stringPostfix) {\r
                        super();\r
                        this.l0Type = l0Type;\r
                        this.binding = binding;\r
@@ -951,10 +1186,11 @@ public abstract class SchemaConversionBase {
                        this.id = false;\r
                        this.getterPrefix = getterPrefix;\r
                        this.getterPostfix = getterPostfix;\r
-                       \r
+                       this.stringPrefix = stringPrefix;\r
+                       this.stringPostfix = stringPostfix;\r
                }\r
                \r
-               public TypeEntry(String l0Type, String binding, String javaType, String defaultValue, String getterPrefix, String getterPostfix, boolean id) {\r
+               public TypeEntry(String l0Type, String binding, String javaType, String defaultValue, String getterPrefix, String getterPostfix, String stringPrefix, String stringPostfix, boolean id) {\r
                        super();\r
                        this.l0Type = l0Type;\r
                        this.binding = binding;\r
@@ -963,6 +1199,8 @@ public abstract class SchemaConversionBase {
                        this.id = id;\r
                        this.getterPrefix = getterPrefix;\r
                        this.getterPostfix = getterPostfix;\r
+                       this.stringPrefix = stringPrefix;\r
+                       this.stringPostfix = stringPostfix;\r
                }\r
                \r
                public String getValueGetterMethod(String name) {\r
@@ -976,6 +1214,153 @@ public abstract class SchemaConversionBase {
                        return getValueGetter("value");\r
                }\r
                \r
+               public String getToString(String name) {\r
+                       return stringPrefix +"("+javaType+")"+name+stringPostfix;\r
+               }\r
+               \r
+               public String getElementToString(String name) {\r
+                       return stringPrefix + name+stringPostfix;\r
+               }\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(topLevelObj, type.getLocalPart());\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(topLevelObj, type.getLocalPart());\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.getLocalPart());\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