]> gerrit.simantics Code Review - simantics/interop.git/blob - org.simantics.xml.sax/src/org/simantics/xml/sax/SchemaConversionBase.java
Replace log4j with slf4j
[simantics/interop.git] / org.simantics.xml.sax / src / org / simantics / xml / sax / SchemaConversionBase.java
1 package org.simantics.xml.sax;
2
3 import java.util.ArrayDeque;
4 import java.util.ArrayList;
5 import java.util.Deque;
6 import java.util.HashMap;
7 import java.util.HashSet;
8 import java.util.List;
9 import java.util.Map;
10 import java.util.Set;
11
12 import javax.xml.bind.JAXBElement;
13 import javax.xml.namespace.QName;
14
15 import org.simantics.utils.datastructures.BijectionMap;
16 import org.simantics.xml.sax.SchemaElement.ElementType;
17 import org.simantics.xml.sax.SchemaObject.ObjectType;
18 import org.simantics.xml.sax.configuration.AttributeComposition;
19 import org.simantics.xml.sax.configuration.Configuration;
20 import org.simantics.xml.sax.configuration.IDProvider;
21 import org.simantics.xml.sax.configuration.IDReference;
22 import org.simantics.xml.sax.configuration.OrderedChild;
23 import org.simantics.xml.sax.configuration.Rename;
24 import org.simantics.xml.sax.configuration.UnrecognizedChildElement;
25 import org.w3._2001.xmlschema.All;
26 import org.w3._2001.xmlschema.Annotated;
27 import org.w3._2001.xmlschema.Any;
28 import org.w3._2001.xmlschema.Attribute;
29 import org.w3._2001.xmlschema.AttributeGroup;
30 import org.w3._2001.xmlschema.ComplexContent;
31 import org.w3._2001.xmlschema.ComplexRestrictionType;
32 import org.w3._2001.xmlschema.ComplexType;
33 import org.w3._2001.xmlschema.Element;
34 import org.w3._2001.xmlschema.ExplicitGroup;
35 import org.w3._2001.xmlschema.ExtensionType;
36 import org.w3._2001.xmlschema.GroupRef;
37 import org.w3._2001.xmlschema.LocalElement;
38 import org.w3._2001.xmlschema.NamedAttributeGroup;
39 import org.w3._2001.xmlschema.NamedGroup;
40 import org.w3._2001.xmlschema.OpenAttrs;
41 import org.w3._2001.xmlschema.RealGroup;
42 import org.w3._2001.xmlschema.Restriction;
43 import org.w3._2001.xmlschema.Schema;
44 import org.w3._2001.xmlschema.SimpleContent;
45 import org.w3._2001.xmlschema.SimpleType;
46 import org.w3._2001.xmlschema.TopLevelAttribute;
47 import org.w3._2001.xmlschema.TopLevelComplexType;
48 import org.w3._2001.xmlschema.TopLevelElement;
49 import org.w3._2001.xmlschema.TopLevelSimpleType;
50 import org.w3._2001.xmlschema.Union;
51
52 public final class SchemaConversionBase {
53         
54         protected Schema schema;
55         protected SchemaConverter converter;
56         protected SchemaConversionComponent component;
57         protected Configuration configuration;
58         
59         public static final String SCHEMA_NS = "http://www.w3.org/2001/XMLSchema";
60         public static final String CONVERSION_NS = "http://www.simantics.org/Layer0";
61         
62         protected Map<String,Map<String,TypeEntry>> typeMap;
63         
64         protected String ontologyURI;
65         protected String className;
66         
67         public SchemaConversionBase(SchemaConverter converter, String ontologyUri, String className) {
68                 this.converter = converter;
69                 this.configuration = converter.getConfiguration();
70                 this.ontologyURI = ontologyUri;
71                 this.className = className;
72                 
73                 initTypes();
74         }
75         
76         protected void initTypes() {
77                 typeMap = new HashMap<String, Map<String,TypeEntry>>();
78                 Map<String,TypeEntry> schemaTypes = new HashMap<String, SchemaConversionBase.TypeEntry>();
79                 typeMap.put(SCHEMA_NS, schemaTypes);
80                 Map<String,TypeEntry> l0Types = new HashMap<String, SchemaConversionBase.TypeEntry>();
81                 typeMap.put(CONVERSION_NS, l0Types);
82                 
83                 schemaTypes.put("string",               new TypeEntry("L0.String",                      "Bindings.STRING", "java.lang.String", "","","","",""));
84                 schemaTypes.put("NMTOKEN",              new TypeEntry("L0.String",                      "Bindings.STRING", "java.lang.String", "","","","",""));
85                 schemaTypes.put("token",                new TypeEntry("L0.String",                      "Bindings.STRING", "java.lang.String", "","","","",""));
86                 schemaTypes.put("ID",                   new TypeEntry("L0.String",                      "Bindings.STRING", "java.lang.String", "","","","","",true));
87                 schemaTypes.put("IDREF",                new TypeEntry("L0.String",                      "Bindings.STRING", "java.lang.String", "","","","",""));
88                 schemaTypes.put("Name",                 new TypeEntry("L0.String",                      "Bindings.STRING", "java.lang.String", "","","","",""));
89                 schemaTypes.put("NCName",               new TypeEntry("L0.String",                      "Bindings.STRING", "java.lang.String", "","","","",""));
90                 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()"));
91                 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()"));
92                 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()"));
93                 schemaTypes.put("gYearMonth",   new TypeEntry("L0.String",                      "Bindings.STRING", "java.lang.String", "","","","",""));
94                 schemaTypes.put("gYear",                new TypeEntry("L0.String",                      "Bindings.STRING", "java.lang.String", "","","","",""));
95                 schemaTypes.put("gMonth",               new TypeEntry("L0.String",                      "Bindings.STRING", "java.lang.String", "","","","",""));
96                 schemaTypes.put("gMonthDay",    new TypeEntry("L0.String",                      "Bindings.STRING", "java.lang.String", "","","","",""));
97                 schemaTypes.put("anyURI",               new TypeEntry("L0.URI",                         "Bindings.STRING", "java.lang.String", "","","","",""));
98                 schemaTypes.put("double",               new TypeEntry("L0.Double",                      "Bindings.DOUBLE", "double", "java.lang.Double.NaN","java.lang.Double.parseDouble(",")","java.lang.Double.toString(",")"));
99                 schemaTypes.put("float",                new TypeEntry("L0.Float",                       "Bindings.FLOAT",  "float",  "java.lang.Float.NaN","java.lang.Float.parseFloat(",")","java.lang.Float.toString(",")"));
100                 schemaTypes.put("decimal",              new TypeEntry("L0.Double",                      "Bindings.DOUBLE", "double", "java.lang.Double.NaN","java.lang.Double.parseDouble(",")","java.lang.Double.toString(",")"));
101                 schemaTypes.put("boolean",              new TypeEntry("L0.Boolean",                     "Bindings.BOOLEAN", "boolean", "false","java.lang.Boolean.parseBoolean(",")","java.lang.Boolean.toString(",")"));
102                 schemaTypes.put("integer",              new TypeEntry("L0.Integer",             "Bindings.INTEGER", "int", "0","java.lang.Integer.parseInt(",")","java.lang.Integer.toString(",")"));
103                 schemaTypes.put("positiveInteger", new TypeEntry("L0.Integer",          "Bindings.INTEGER", "int", "0","java.lang.Integer.parseInt(",")","java.lang.Integer.toString(",")"));
104                 schemaTypes.put("nonPositiveInteger", new TypeEntry("L0.Integer",       "Bindings.INTEGER", "int", "0","java.lang.Integer.parseInt(",")","java.lang.Integer.toString(",")"));
105                 schemaTypes.put("nonNegativeInteger", new TypeEntry("L0.Integer",       "Bindings.INTEGER", "int", "0","java.lang.Integer.parseInt(",")","java.lang.Integer.toString(",")"));
106                 schemaTypes.put("negativeInteger", new TypeEntry("L0.Integer",          "Bindings.INTEGER", "int", "0","java.lang.Integer.parseInt(",")","java.lang.Integer.toString(",")"));
107                 schemaTypes.put("unsignedInt",  new TypeEntry("L0.Integer",             "Bindings.INTEGER", "int", "0","java.lang.Integer.parseInt(",")","java.lang.Integer.toString(",")"));
108                 schemaTypes.put("int",                  new TypeEntry("L0.Integer",                     "Bindings.INTEGER", "int", "0","java.lang.Integer.parseInt(",")","java.lang.Integer.toString(",")"));
109                 schemaTypes.put("short",                new TypeEntry("L0.Integer",                     "Bindings.INTEGER", "int", "0","java.lang.Integer.parseInt(",")","java.lang.Integer.toString(",")"));
110                 schemaTypes.put("unsignedShort",new TypeEntry("L0.Integer",                     "Bindings.INTEGER", "int", "0","java.lang.Integer.parseInt(",")","java.lang.Integer.toString(",")"));
111                 schemaTypes.put("byte",                 new TypeEntry("L0.Byte",                        "Bindings.BYTE", "byte", "0","java.lang.Byte.parseByte(",")","java.lang.Byte.toString(",")"));
112                 schemaTypes.put("unsignedByte", new TypeEntry("L0.Byte",                        "Bindings.BYTE", "byte", "0","java.lang.Byte.parseByte(",")","java.lang.Byte.toString(",")"));
113                 schemaTypes.put("long",                 new TypeEntry("L0.Long",                        "Bindings.LONG", "long", "0","java.lang.Long.parseLong(",")","java.lang.Long.toString(",")"));
114                 schemaTypes.put("unsignedLong", new TypeEntry("L0.Long",                        "Bindings.LONG", "long", "0","java.lang.Long.parseLong(",")","java.lang.Long.toString(",")"));
115                 schemaTypes.put("base64Binary", new TypeEntry("L0.ByteArray",           "Bindings.BYTE_ARRAY", "byte[]", "new byte[0]","java.util.Base64.getDecoder().decode(",".replaceAll(\"\\n\", \"\").getBytes(java.nio.charset.StandardCharsets.UTF_8))","java.util.Base64.getEncoder().encodeToString(",")"));
116                 
117                 l0Types.put("doubleArray",              new TypeEntry("L0.DoubleArray",  "Bindings.DOUBLE_ARRAY", "double[]", null,null,null,"java.lang.Double.toString(",")"));
118                 l0Types.put("stringArray",              new TypeEntry("L0.StringArray",  "Bindings.STRING_ARRAY", "string[]", null,null,null,"",""));
119         }
120         
121         protected TypeEntry getTypeEntry(QName type) {
122                 Map<String,TypeEntry> types = typeMap.get(type.getNamespaceURI());
123                 if (types == null)
124                         return null;
125                 TypeEntry entry = types.get(type.getLocalPart());
126                 return entry;
127         }
128         protected TypeEntry getTypeEntry(String type) {
129                 for (Map<String,TypeEntry> types : typeMap.values()) {
130                         TypeEntry entry = types.get(type);
131                         if (entry != null)
132                                 return entry;
133                 }
134                 return null;
135         }
136         
137         protected String getL0TypeFromPrimitiveType(QName primitiveType) {
138                 TypeEntry entry = getTypeEntry(primitiveType);
139                 if (entry == null)
140                         return null;
141                 return entry.l0Type;
142         }
143         
144         protected String getL0Type(QName primitiveType) {
145                 String type = getL0TypeFromPrimitiveType(primitiveType);
146                 if (type != null)
147                         return type;
148                 SchemaObject simpleTypeObj = simpleTypeName.get(primitiveType.getLocalPart());
149                 if (simpleTypeObj == null)
150                         return null;
151                 SimpleType simpleType = simpleTypeObj.getSimpleType();
152                 while (simpleType != null) {
153                         QName base = simpleType.getRestriction().getBase();
154                         if (base != null)
155                                 return getL0Type(base);
156                         simpleType = simpleType.getRestriction().getSimpleType();
157                 }
158                 return null;
159         }
160         
161         protected String getBindingFromPrimitiveType(QName primitiveType) {
162                 TypeEntry entry = getTypeEntry(primitiveType);
163                 if (entry == null)
164                         return null;
165                 return entry.binding;
166         }
167         
168         protected String getJavaTypeFromPrimitiveType(QName primitiveType) {
169                 TypeEntry entry = getTypeEntry(primitiveType);
170                 if (entry == null)
171                         return null;
172                 return entry.javaType;
173         }
174         
175         
176         public void init(Schema schema) {       
177                 this.schema = schema;
178                 
179                 preload();
180         }
181         
182         public void handle(SchemaConversionComponent component) {
183                 this.component = component;
184                 for (OpenAttrs attrs : schema.getSimpleTypeOrComplexTypeOrGroup()) {
185                         if (attrs instanceof TopLevelAttribute) {
186                                 handle((TopLevelAttribute)attrs);
187                                 
188                         } else if (attrs instanceof TopLevelComplexType) {
189                                 handleComplexType(complexTypes.get(attrs));
190                         } else if (attrs instanceof TopLevelElement) {
191                                 handleElement(elements.get(attrs));
192                         } else if (attrs instanceof TopLevelSimpleType) {
193                                 handleSimpleType(simpleTypes.get(attrs));
194                         } else if (attrs instanceof NamedAttributeGroup) {
195                                 handle((NamedAttributeGroup)attrs);
196                         } else if (attrs instanceof NamedGroup) {
197                                 handle((NamedGroup)attrs);
198                         } else {
199                                 System.out.println(attrs.getClass().getName());
200                         }
201                 }
202         }
203         
204         private Map<String,SchemaObject> elementName = new HashMap<>();
205         private Map<String,SchemaObject> complexTypeName = new HashMap<>();
206         private Map<String,SchemaObject> simpleTypeName = new HashMap<>();
207         private Map<String,SchemaObject> modelGroupName = new HashMap<>();
208         private Map<String,SchemaObject> attrName = new HashMap<>();
209         private Map<Element,SchemaObject> elements = new HashMap<>();
210         private Map<ComplexType,SchemaObject> complexTypes = new HashMap<>();
211         private Map<SimpleType,SchemaObject> simpleTypes = new HashMap<>();
212         private Map<NamedGroup,SchemaObject> modelGroups = new HashMap<>();
213         private Map<Attribute,SchemaObject> attributes = new HashMap<>();
214         
215         private SchemaObject _getWithName(QName name) {
216                 SchemaObject obj = elementName.get(name.getLocalPart());
217                 if (obj == null)
218                         obj = complexTypeName.get(name.getLocalPart());
219                 if (obj == null)
220                         obj = simpleTypeName.get(name.getLocalPart());
221                 if (obj == null)
222                         obj = attrName.get(name.getLocalPart());
223                 return obj;
224         }
225         
226         protected SchemaObject getWithName(QName name) {
227                 SchemaObject obj = _getWithName(name);
228                 if (obj != null)
229                         return obj;
230                 if (name.getNamespaceURI() != null) {
231                         for (SchemaConverter sc : converter.getConverter(name.getNamespaceURI())) {
232                                 if (sc.base != null) {
233                                         obj = sc.base._getWithName(name);
234                                         if (obj != null) {
235                                                 return obj;
236                                         }
237                                 }
238                         }               
239                 }
240                 return null;
241         }
242         
243         private NamedAttributeGroup _getAttributeGroup(QName name) {
244                 for (OpenAttrs attrs : schema.getSimpleTypeOrComplexTypeOrGroup()) {
245                         if (attrs instanceof NamedAttributeGroup) {
246                                 NamedAttributeGroup group = (NamedAttributeGroup)attrs;
247                                 if (group.getName().equals(name.getLocalPart()))
248                                         return group;
249                         }
250                 }
251                 return null;
252         }
253
254         public NamedAttributeGroup getAttributeGroup(QName name) {
255                 NamedAttributeGroup group = _getAttributeGroup(name);
256                 if (group != null)
257                         return group;
258                 if (name.getNamespaceURI() != null) {
259                         for (SchemaConverter sc : converter.getConverter(name.getNamespaceURI())) {
260                                 if (sc.base != null) {
261                                         group = sc.base._getAttributeGroup(name);
262                                         if (group != null) {
263                                                 return group;
264                                         }
265                                 }
266                         }       
267                 }
268                 return null;
269         }
270         
271         private SchemaObject _getElement(QName name) {
272                 return elementName.get(name.getLocalPart());
273         }
274         
275         protected SchemaObject getElement(QName name) {
276                 SchemaObject obj = _getElement(name);
277                 if (obj != null)
278                         return obj;
279                 if (name.getNamespaceURI() != null) {
280                         for (SchemaConverter sc : converter.getConverter(name.getNamespaceURI())) {
281                                 if (sc.base != null) {
282                                         obj = sc.base._getElement(name);
283                                         if (obj != null) {
284                                                 return obj;
285                                         }
286                                 }
287                         }               
288                 }
289                 return null;
290         }
291         
292         protected SchemaObject getElement(Element element) {
293                 return elements.get(element);
294         }
295         
296         
297         private SchemaObject _getComplexType(QName name) {
298                 return complexTypeName.get(name.getLocalPart());
299         }
300         
301         protected SchemaObject getComplexType(QName name) {
302                 SchemaObject obj = _getComplexType(name);
303                 if (obj != null)
304                         return obj;
305                 if (name.getNamespaceURI() != null) {
306                         for (SchemaConverter sc : converter.getConverter(name.getNamespaceURI())) {
307                                 if (sc.base != null) {
308                                         obj = sc.base._getComplexType(name);
309                                         if (obj != null) {
310                                                 return obj;
311                                         }
312                                 }
313                         }               
314                 }
315                 return null;
316         }
317         
318         protected SchemaObject getComplexType(ComplexType complexType) {
319                 return complexTypes.get(complexType);
320         }
321         
322         private SchemaObject _getSimpleType(QName name) {
323                 return simpleTypeName.get(name.getLocalPart());
324         }
325         
326         protected SchemaObject getSimpleType(QName name) {
327                 SchemaObject obj = _getSimpleType(name);
328                 if (obj != null)
329                         return obj;
330                 if (name.getNamespaceURI() != null) {
331                         for (SchemaConverter sc : converter.getConverter(name.getNamespaceURI())) {
332                                 if (sc.base != null) {
333                                         obj = sc.base._getSimpleType(name);
334                                         if (obj != null) {
335                                                 return obj;
336                                         }
337                                 }
338                         }               
339                 }
340                 return null;
341         }
342         
343         protected SchemaObject getSimpleType(SimpleType simpleType) {
344                 return simpleTypes.get(simpleType);
345         }
346         
347         protected SchemaObject getWithObj(SchemaObject referrer, OpenAttrs attrs) {
348                 // FIXME : this method cannot handle references to other schemas.
349                 SchemaObject obj = null;
350                 if (attrs instanceof Element)
351                         obj = elements.get(attrs);
352                 else if (attrs instanceof ComplexType)
353                         obj = complexTypes.get(attrs);
354                 else if (attrs instanceof SimpleType) 
355                         obj = simpleTypes.get(attrs);
356                 if (obj == null){
357                         throw new RuntimeException("Cannot locate referred object " + attrs + " when handling " + referrer.getName());
358                 }
359                 return obj;
360         }
361         
362         private void preload() {
363                 Deque<SchemaObject> stack = new ArrayDeque<SchemaObject>();
364                 //stack.addAll(schema.getSimpleTypeOrComplexTypeOrGroup());
365                 for (OpenAttrs attrs : schema.getSimpleTypeOrComplexTypeOrGroup()) {
366                         if (attrs instanceof Element) {
367                                 Element element = (Element)attrs;
368                                 SchemaObject obj = new SchemaObject(this,element);
369                                 obj.setRename(getRename(element));
370                                 stack.push(obj);
371                         } else if (attrs instanceof ComplexType) {
372                                 ComplexType complexType = (ComplexType)attrs;
373                                 SchemaObject obj = new SchemaObject(this,complexType);
374                                 obj.setRename(getRename(complexType));
375                                 stack.push(obj);
376                         } else if (attrs instanceof SimpleType) {
377                                 SimpleType simpleType = (SimpleType)attrs;
378                                 SchemaObject obj = new SchemaObject(this,simpleType);
379                                 stack.push(obj);
380                         }  else if (attrs instanceof Attribute) {
381                                 Attribute attribute = (Attribute)attrs;
382                                 SchemaObject obj = new SchemaObject(this, attribute);
383                                 stack.push(obj);
384                         } else if (attrs instanceof AttributeGroup) {
385                                 // Attribute groups are not cached
386                         } else if (attrs instanceof NamedGroup) {
387                                 NamedGroup group = (NamedGroup)attrs;
388                                 SchemaObject obj = new SchemaObject(this,group);
389                                 stack.push(obj);
390                         } else {
391                                 System.out.println(attrs.getClass().getName());
392                         }
393                 }
394                 
395                 while (!stack.isEmpty()) {
396                         SchemaObject object = stack.pop();
397                         switch (object.getType()) {
398                         case COMPLEX_TYPE:{
399                                 ComplexType ct = object.getComplexType();
400                                 if (ct.getName() != null && ct.getName().length() > 0 && ct instanceof TopLevelComplexType)
401                                         complexTypeName.put(ct.getName(), object);
402                                 complexTypes.put(ct, object);
403                                 if (ct.getChoice() != null) {
404                                         preload(object,ct.getChoice(), stack);
405                                 }
406                                 if (ct.getSequence() != null) {
407                                         preload(object,ct.getSequence(), stack);
408                                 }
409                                 if (ct.getAll() != null) {
410                                         preload(object,ct.getAll(), stack);
411                                 }
412                                 if (ct.getGroup() != null)
413                                         throw new RuntimeException("Groups not supported");
414                                 if (ct.getComplexContent() != null) {
415                                         ComplexContent cc = ct.getComplexContent();
416                                         ExtensionType extensionType = cc.getExtension();
417                                         if (extensionType != null) {
418                                                 if (extensionType.getChoice() != null) {
419                                                         preload(object,extensionType.getChoice(), stack);
420                                                 }
421                                                 if (extensionType.getSequence()!= null) {
422                                                         preload(object,extensionType.getSequence(), stack);
423                                                 }
424                                                 if (extensionType.getAll()!= null) {
425                                                         preload(object,extensionType.getAll(), stack);
426                                                 }
427                                                 if (extensionType.getGroup() != null) {
428                                                         throw new RuntimeException("Groups not supported");
429                                                         //preload(object,extensionType.getGroup(), stack);
430                                                 }
431                                         }
432                                 }
433                                 if (ct.getSimpleContent() != null) {
434                                         SimpleContent cc = ct.getSimpleContent();
435                                         ExtensionType extensionType = cc.getExtension();
436                                         if (extensionType != null) {
437                                                 if (extensionType.getChoice() != null) {
438                                                         preload(object,extensionType.getChoice(), stack);
439                                                 }
440                                                 if (extensionType.getSequence()!= null) {
441                                                         preload(object,extensionType.getSequence(), stack);
442                                                 }
443                                                 if (extensionType.getAll()!= null) {
444                                                         preload(object,extensionType.getAll(), stack);
445                                                 }
446                                                 if (extensionType.getGroup() != null)
447                                                         throw new RuntimeException("Groups not supported");
448                                         }
449                                 }
450                                 break;
451                         } 
452                         case ELEMENT:{
453                                 Element e = object.getElement();
454                                 if (e instanceof TopLevelElement)
455                                         elementName.put(e.getName(), object);
456                                 elements.put(e, object);
457                                 if (e.getComplexType() != null)
458                                         stack.push(new SchemaObject(this,object,e.getComplexType()));
459                                 if (e.getSimpleType() != null)
460                                         stack.push(new SchemaObject(this,object,e.getSimpleType()));
461                                 break;
462                         } 
463                         case SIMPLE_TYPE:{
464                                 SimpleType e = object.getSimpleType();
465                                 if (e instanceof TopLevelSimpleType)
466                                         simpleTypeName.put(e.getName(), object);
467                                 simpleTypes.put(e, object);
468                                 break;
469                         } 
470                         case MODEL_GROUP:{
471                                 NamedGroup e = object.getModelGroup();
472                                 modelGroupName.put(e.getName(), object);
473                                 modelGroups.put(e, object);
474                                 break;
475                         }
476                         case ATTRIBUTE: {
477                                 Attribute e = object.getAttribute();
478                                 attrName.put(e.getName(), object);
479                                 attributes.put(e, object);
480                                 break;
481                         }
482                         }
483                 } // while
484         }
485         
486         private void preload(SchemaObject parent,ExplicitGroup eg, Deque<SchemaObject> stack) {
487                 for (Object o : eg.getParticle()) {
488                         if (o instanceof JAXBElement<?>) {
489                                 JAXBElement<?> element = (JAXBElement<?>)o;
490                                 Object elemValue = element.getValue();
491                                 if (elemValue instanceof Element) {
492                                         SchemaObject obj = new SchemaObject(this,parent,(Element)elemValue);
493                                         obj.setRename(getRename((Element)elemValue));
494                                         stack.add(obj);
495                                 } else if (elemValue instanceof ExplicitGroup) {
496                                         preload(parent,(ExplicitGroup)elemValue, stack);
497                                 } else if (elemValue instanceof RealGroup) {
498                                         preload(parent,(RealGroup)elemValue, stack);
499                                 } else {
500                                         throw new RuntimeException("Unknown ExplicitGroup element " + elemValue.getClass().getName());
501                                 }
502                         } else if (o instanceof Any){
503                                 
504                         } else {
505                                 throw new RuntimeException("Unknown ExplicitGroup reference " + o.getClass().getName());
506                         }
507                 }
508         }
509         
510         private void preload(SchemaObject parent, RealGroup eg, Deque<SchemaObject> stack) {
511                 System.out.println(eg); 
512                 if (eg instanceof NamedGroup) {
513                         SchemaObject obj = new SchemaObject(this,parent,(NamedGroup)eg);
514                         stack.add(obj);
515                 }
516         }
517
518         
519         protected void handle(TopLevelAttribute topLevelAttribute) {
520                 handle(null, topLevelAttribute);
521         }
522         
523         protected void handleSimpleType(SchemaObject topLevelSimpleType) {
524                 handleSimpleType(null,topLevelSimpleType);
525         }
526         
527         protected void handle(NamedAttributeGroup namedAttributeGroup){
528                 handle(null, namedAttributeGroup);
529         }
530         
531         protected void handle(NamedGroup namedAttributeGroup){
532                 handle(null, namedAttributeGroup);
533         }
534         
535         protected QName getComplexTypeBase(ComplexType complexType) {
536                 if (complexType == null)
537                         return null;
538                 ComplexContent complexContent = complexType.getComplexContent();
539                 if (complexContent != null) {
540                         ExtensionType extensionType = complexContent.getExtension();
541                         if (extensionType != null) {
542                                 QName type = extensionType.getBase();
543                                 return type;
544                         }
545                         ComplexRestrictionType restriction = complexContent.getRestriction();
546                         if (restriction != null)
547                                 return restriction.getBase();
548                 }
549                 if (complexType.isMixed()) {
550                         // Handle characters data of mixed ComplexType as String.
551                         return new QName(SCHEMA_NS, "string");
552                 }
553                 return null;
554         }
555         
556         protected QName getSimpleTypeBase(SimpleType simpleType) {
557 //              if (simpleType == null)
558 //                      return null;
559 //              return simpleType.getRestriction().getBase();
560                 
561                 Restriction restriction = simpleType.getRestriction();
562                 if (restriction != null) {
563                         QName base = restriction.getBase();
564                         return base;
565                 } else if (simpleType.getId() != null) {
566                         throw new RuntimeException(simpleType.getName() + " restriction error");
567                 } else if (simpleType.getUnion() != null) {
568                         Union union = simpleType.getUnion();
569                         if (union.getMemberTypes().size() > 0) {
570                                 QName base = null;
571                                 for (QName type : union.getMemberTypes()) {
572                                         QName sType = null;
573                                         TypeEntry entry = getTypeEntry(type);
574                                         if (entry == null) {
575                                                 //SchemaObject obj = simpleTypeName.get(type.getLocalPart());
576                                                 SchemaObject obj = getSimpleType(type);
577                                                 if (obj == null)
578                                                         throw new RuntimeException(simpleType.getName() + " union has unresolved reference " + type.getLocalPart());
579                                                 sType = getSimpleTypeBase(obj.getSimpleType());
580                                         } else {
581                                                 sType = type;
582                                         }
583                                         if (base == null)
584                                                 base = sType;
585                                         else if (!base.equals(sType)) {
586                                                 //FIXME : throw new RuntimeException(simpleType.getName() + " union has incompatible member types");
587                                                 // fall back to string. 
588                                                 base = new QName(SCHEMA_NS, "string");
589                                                 
590                                         }
591                                 }
592                                 return base;
593                         } else {
594                                 if (union.getSimpleType().size() == 0)
595                                         throw new RuntimeException(simpleType.getName() + " union error");
596                                 for (SimpleType s : union.getSimpleType()) {
597                                         if (restriction == null)
598                                                 restriction = s.getRestriction();
599                                         else  {
600                                                 Restriction r = s.getRestriction();
601                                                 if (!r.getBase().equals(restriction.getBase())) {
602                                                         Inheritance rI = new Inheritance("");
603                                                         getAtomicTypeInheritance(r.getBase(), rI);
604                                                         Inheritance restI = new Inheritance("");
605                                                         getAtomicTypeInheritance(restriction.getBase(), restI);
606                                                         if (!rI.atomicType.l0Type.equals(restI.atomicType.l0Type))
607                                                                 throw new RuntimeException(simpleType.getName() + " union has incompatible restriction bases");
608                                                 }
609                                         }
610                                 }
611                                 QName base = restriction.getBase();
612                                 return base;
613                         }
614                 } else if (simpleType.getList() != null) {
615                         // FIXME: callers cannot get the information that we have a list.
616                         org.w3._2001.xmlschema.List list = simpleType.getList();
617                         return list.getItemType();
618                 } else {
619                         throw new RuntimeException(simpleType.getName() + " restriction error");
620                 }
621         }
622         
623         protected QName getElementBase(Element element) {
624                 ComplexType complexType = element.getComplexType();
625                 SimpleType simpleType = element.getSimpleType();
626                 if (complexType != null)
627                         return getComplexTypeBase(complexType);
628                 if (simpleType != null) {
629                         return getSimpleTypeBase(simpleType);
630                 }
631                 return null;
632         }
633         
634         private void handleAttributes(SchemaObject complexType, List<Annotated> attributeOrAttributeGroup) {
635                 //name = getComplexTypePrefix()+complexType.getName()
636                 
637                 Set<Annotated> handled = handleAttributeCompositions(complexType,attributeOrAttributeGroup);
638                 for (Annotated annotated : attributeOrAttributeGroup) {
639                         if (handled.contains(annotated))
640                                 continue;
641                         if (annotated instanceof Attribute) {
642                                 handle(complexType,(Attribute)annotated);
643                         } else if (annotated instanceof AttributeGroup){
644                                 handle(complexType,(AttributeGroup)annotated);
645                                 //comment("AttributeGroup " + ((AttributeGroup)annotated).getRef().getLocalPart());
646                         } else {
647                                 throw new RuntimeException();
648                         }
649                 }
650         }
651         
652         protected void handleAttributes(SchemaObject simpleTypeObj) {
653                 component.handleAttributes(simpleTypeObj);
654         }
655         
656         protected void handleExtensionAttributes(SchemaObject complexType) {
657                 ComplexContent complexContent = complexType.getComplexType().getComplexContent();
658                 if (complexContent != null) {
659                         ExtensionType extensionType = complexContent.getExtension();
660                         if (extensionType != null) {
661                                 handleAttributes(complexType, extensionType.getAttributeOrAttributeGroup());
662                         }
663                 }
664                 SimpleContent simpleContent = complexType.getComplexType().getSimpleContent();
665                 if (simpleContent != null) {
666                         ExtensionType extensionType = simpleContent.getExtension();
667                         if (extensionType != null) {
668                                 handleAttributes(complexType, extensionType.getAttributeOrAttributeGroup());
669                         }
670                 }
671         }
672         
673         
674         
675         protected void handleComplexTypeAttributes(SchemaObject complexType) {          
676                 handleAttributes(complexType,complexType.getComplexType().getAttributeOrAttributeGroup());
677         }
678         
679         protected void handleElementComplexTypeAttributes(SchemaObject complexType) {
680                 if (complexType != null) {
681                         handleComplexTypeAttributes(complexType);
682                         handleExtensionAttributes(complexType);
683                 }
684         }
685         
686         protected void handleElementSimpleTypeAttributes(SchemaObject simpleType) {
687                 if (simpleType != null) {
688                         handleAttributes(simpleType);
689                 }
690         }
691         
692         protected Set<Annotated> handleAttributeCompositions(SchemaObject obj, List<Annotated> attributeOrAttributeGroup) {
693                 
694                 Set<Annotated> handled = new HashSet<Annotated>();
695                 for (JAXBElement<?> e : configuration.getConversionRule()) {
696                         if (e.getValue() instanceof AttributeComposition) {
697                                 AttributeComposition composition = (AttributeComposition)e.getValue();
698                                 if (composition.getAttribute().size() < 2)
699                                         throw new RuntimeException("Attribute Composition is not valid");
700                                 BijectionMap<org.simantics.xml.sax.configuration.Attribute, Annotated> map = new BijectionMap<org.simantics.xml.sax.configuration.Attribute, Annotated>();
701                                 for (org.simantics.xml.sax.configuration.Attribute a : composition.getAttribute()) {
702                                         for (Annotated annotated : attributeOrAttributeGroup) {
703                                                 if (annotated instanceof Attribute) {
704                                                         Attribute attribute = (Attribute)annotated;
705                                                         QName type = getBaseType(attribute);
706                                                         if (a.getName().equals(attribute.getName()) && type != null && a.getType().equals(type.getLocalPart())) {
707                                                                 map.map(a, attribute);
708                                                         }
709                                                 }
710                                         }
711                                 }
712                                 if (composition.getAttribute().size() == map.size()) {
713                                         handled.addAll(map.getRightSet());
714                                         handleAttributeComposition(obj, composition, map);      
715                                 }
716                         }
717                 }
718                 return handled;
719         }
720         
721         protected QName getBaseType(Attribute attribute) {
722                 if (attribute.getType() != null)
723                         return attribute.getType();
724                 if (attribute.getRef() != null)
725                         return attribute.getRef();
726                 SimpleType simpleType = attribute.getSimpleType();
727                 if (simpleType != null) {
728                         Restriction restriction = simpleType.getRestriction();
729                         if (restriction != null)
730                                 if (restriction.getBase() != null)
731                                         return restriction.getBase();
732                 }
733                 return null;
734         }
735         
736         protected QName getPrimitiveType(Attribute attribute) {
737                 QName type = getBaseType(attribute);
738                 String b = getBindingFromPrimitiveType(type);
739                 while (b==null && type != null) {
740                         SchemaObject baseType = simpleTypeName.get(type.getLocalPart());
741                         if (baseType != null) {
742                                 Restriction restriction = baseType.getSimpleType().getRestriction();
743                                 if (restriction != null)
744                                         if (restriction.getBase() != null) {
745                                                 type = restriction.getBase();
746                                                 b = getBindingFromPrimitiveType(type);
747                                         }
748                         }
749                 }
750                 return type;
751         }
752         
753         private SchemaObject _getAttribute(QName name) {
754                 return attrName.get(name.getLocalPart());
755         }
756         
757         protected Attribute getRefAttribute(QName ref) {
758 //              for (OpenAttrs attrs : schema.getSimpleTypeOrComplexTypeOrGroup()) {
759 //                      if (attrs instanceof TopLevelAttribute) {
760 //                              TopLevelAttribute attribute = (TopLevelAttribute)attrs;
761 //                              if (attribute.getName().equals(ref.getLocalPart()))
762 //                                      return attribute;
763 //                      }
764 //              }
765                 SchemaObject obj = _getAttribute(ref);
766                 if (obj != null)
767                         return obj.getAttribute();
768                 if (ref.getNamespaceURI() != null) {
769                         for (SchemaConverter sc : converter.getConverter(ref.getNamespaceURI())) {
770                                 if (sc.base != null) {
771                                         obj = sc.base._getAttribute(ref);
772                                         if (obj != null) {
773                                                 return obj.getAttribute();
774                                         }
775                                 }
776                         }               
777                 }
778                 return null;
779         }
780         
781         //protected abstract void handleAttributeComposition(SchemaObject obj, AttributeComposition composition, BijectionMap<org.simantics.xml.sax.configuration.Attribute, Annotated> attributes);
782         protected void handleAttributeComposition(SchemaObject obj, AttributeComposition composition, BijectionMap<org.simantics.xml.sax.configuration.Attribute, Annotated> attributes) {
783                 component.handleAttributeComposition(obj, composition, attributes);
784         }
785         
786         
787         
788         
789         protected void handleComplexType(SchemaObject complexType) {
790 //              handleComplexTypeAttributes(complexType);
791 //              handleComplexTypeExtension(complexType);
792 //              handleExtensionAttributes(complexType);
793                 component.handleComplexType(complexType);
794         }
795         
796         protected void handleElement(SchemaObject topLevelElement) {
797 //              LocalComplexType complexType = topLevelElement.getElement().getComplexType();
798 //              
799 //              if (complexType != null) {
800 //                      SchemaObject complextTypeObj = complexTypes.get(complexType);
801 //                      handleElementComplexTypeAttributes(complextTypeObj);
802 //                      handleComplexTypeExtension(complextTypeObj);
803 //              }       
804                 component.handleElement(topLevelElement);
805         }
806         
807         protected enum RefType{Element,Reference,Type};
808         
809         protected void handleIndicator(SchemaObject parent, SchemaElement indicator, SchemaElement element, String refName, RefType refType, String baseRelationName) {
810                 component.handleIndicator(parent, indicator, element, refName, refType, baseRelationName);
811         }
812         protected void handleIndicator(SchemaObject parent, SchemaElement indicator, SchemaElement any) {
813                 component.handleIndicator(parent, indicator, any);
814         }
815         protected void handle(SchemaObject parent, SchemaElement indicator, List<SchemaElement> elements) {
816                 //component.handle(parent, indicator, elements);
817                 // Generate combined relation
818                 String baseRelationName = null;
819                 if (indicator.getType() == SchemaElement.ElementType.CHOICE) {
820                         String name = getChoiceName(elements);
821                         if (name != null)
822                                 baseRelationName = component.handleChoice(parent, indicator, elements, name);
823                 }
824                 
825                 if (indicator.getType() == SchemaElement.ElementType.SEQUENCE || indicator.getType() == SchemaElement.ElementType.CHOICE) {
826                         for (SchemaElement e : elements) {
827                                 handle(parent, indicator, e, baseRelationName);
828                         }
829                 }
830         }
831         
832         protected void handle(SchemaObject parent, ExplicitGroup eg, SchemaElement.ElementType indicator) {
833                 handle(parent, new SchemaElement(eg, indicator));
834         }
835         
836         protected void handle(SchemaObject parent, GroupRef eg, SchemaElement.ElementType indicator) {
837                 handle(parent, new SchemaElement(eg, indicator));
838         }
839         
840         protected void handle(SchemaObject parent, SchemaElement indicator) {
841                 
842                 
843                 List<SchemaElement> elements = new ArrayList<SchemaElement>();
844                 List<SchemaElement> choices = new ArrayList<SchemaElement>();
845                 List<SchemaElement> sequences = new ArrayList<SchemaElement>();
846                 List<SchemaElement> alls = new ArrayList<SchemaElement>();
847                 List<SchemaElement> anys = new ArrayList<SchemaElement>();
848                 List<SchemaElement> groups = new ArrayList<SchemaElement>();
849                 
850                 for (Object o : indicator.getGroup().getParticle()) {
851                         if (o instanceof JAXBElement<?>) {
852                                 JAXBElement<?> element = (JAXBElement<?>)o;
853                                 Object elemValue = element.getValue();
854                                 if (elemValue instanceof LocalElement) {
855                                         LocalElement localElement = (LocalElement)elemValue;
856                                         elements.add(new SchemaElement(indicator,localElement, ElementType.ELEMENT));
857                                 } else if (elemValue instanceof All) {
858                                         alls.add(new SchemaElement(indicator,(All)elemValue, ElementType.ALL));
859                                 } else if (elemValue instanceof ExplicitGroup) {
860                                         QName qname = element.getName();
861                                         if ("choice".equals(qname.getLocalPart())) {
862                                                 choices.add(new SchemaElement(indicator,(ExplicitGroup)elemValue, ElementType.CHOICE));
863                                         } else if ("sequence".equals(qname.getLocalPart())) {
864                                                 sequences.add(new SchemaElement(indicator,(ExplicitGroup)elemValue, ElementType.SEQUENCE));
865                                         }
866                                 } else if (elemValue instanceof RealGroup) {
867                                         if (elemValue instanceof GroupRef) {
868                                                 groups.add(new SchemaElement(indicator,(GroupRef)elemValue, ElementType.GROUP_REF));
869                                         } else if (elemValue instanceof NamedGroup) {
870                                                 groups.add(new SchemaElement(indicator,(NamedGroup)elemValue, ElementType.NAMED_GROUP));
871                                         } else {
872                                                 throw new RuntimeException("Unknown ExplicitGroup element " + elemValue.getClass().getName());
873                                         }
874                                 } else {
875                                         throw new RuntimeException("Unknown ExplicitGroup element " + elemValue.getClass().getName());
876                                 }
877                         } else if (o instanceof Any){
878                                 anys.add(new SchemaElement(indicator,(Any)o, ElementType.ANY));
879                         } else {
880                                 throw new RuntimeException("Unknown ExplicitGroup reference " + o.getClass().getName());
881                         }
882                 }
883                 
884                 if (elements.size() == 0 && choices.size() == 0 && sequences.size() == 0 && alls.size() == 0 && anys.size() == 0 && groups.size() == 0) {
885                         return;
886                 }
887                 
888                 if (indicator.getType() == SchemaElement.ElementType.SEQUENCE) {
889                         if (indicator.getRestriction().single()) {
890                                 if (elements.size() > 0) {
891                                         for (SchemaElement e : sequences) {
892                                                 handle(parent, e);
893                                         }
894                                         for (SchemaElement c : choices) {
895                                                 handle(parent, c);
896                                         }
897                                         
898                                         for (SchemaElement c : alls) {
899                                                 handle(parent, c);
900                                         }
901                                         
902                                         for (SchemaElement c : groups) {
903                                                 handle(parent, c);
904                                         }
905                                         handle(parent, indicator, elements);
906                                         for (SchemaElement a : anys) {
907                                                 handleIndicator(parent, indicator, a);
908                                         }
909                                 } else {
910                                         if (sequences.size() > 0) {
911                                                 throw new RuntimeException("Cannot handle Sequence with inner Sequences");
912                                         }
913                                         for (SchemaElement c : choices) {
914                                                 handle(parent, c);
915                                         }
916                                         for (SchemaElement a : anys) {
917                                                 handleIndicator(parent, indicator, a);
918                                         }
919                                         for (SchemaElement c : groups) {
920                                                 handle(parent, c);
921                                         }
922                                 }
923                         } else {
924                                 if (choices.size() == 1 && sequences.size() == 0 && alls.size() == 0 && groups.size() == 0) {
925                                         // special case: handle lone choice inside sequence with maxOccurs > 1 
926                                         SchemaElement choice = choices.get(0);
927                                         // move multiplicity restrictions to choice
928                                         if (indicator.getRestriction().max == -1 || (choice.getRestriction().max > 0 && indicator.getRestriction().max > choice.getRestriction().max))
929                                                 choice.getRestriction().max = indicator.getRestriction().max;
930                                         if (indicator.getRestriction().min == 0 || choice.getRestriction().min > indicator.getRestriction().min)
931                                                 choice.getRestriction().min = indicator.getRestriction().min;
932                                         handle(parent, choice, elements);
933                                         return;
934                                 }
935                                 if (sequences.size() > 0 || choices.size() > 0 || alls.size() > 0 || groups.size() > 0) {
936                                         throw new RuntimeException("Cannot handle Sequence with inner ExplicitGroups");
937                                 }
938                                 handle(parent, indicator, elements);
939                                 for (SchemaElement a : anys) {
940                                         handleIndicator(parent, indicator, a);
941                                 }
942                         }
943                 
944                 } else if (indicator.getType() == SchemaElement.ElementType.CHOICE){
945                         if (indicator.getRestriction().single()) {
946                                 if (sequences.size()> 0 || choices.size() > 0 || alls.size() > 0 || anys.size() > 0 || groups.size() > 0) {
947                                         throw new RuntimeException("Cannot handle Choice that contains something else than Elements");
948                                         //System.out.println("Cannot handle Choice that contains something else than Elements");
949                                         //return;
950                                 }
951                                 handle(parent, indicator, elements);
952                                 
953                         } else {
954                                 if (sequences.size() > 0 || choices.size() > 0 || alls.size() > 0 || groups.size() > 0) {
955                                         throw new RuntimeException("Cannot handle Choice with inner ExplicitGroups");
956                                         //System.out.println("Cannot handle Choice with inner ExplicitGroups");
957                                         //return;
958                                 }
959                                 handle(parent, indicator,  elements);
960                                 for (SchemaElement a : anys) {
961                                         handleIndicator(parent, indicator, a);
962                                 }
963                         }
964                 } else if (indicator.getType() == ElementType.ALL) {
965                         if (sequences.size()> 0 || choices.size() > 0 || alls.size() > 0 || anys.size() > 0  || groups.size() > 0) {
966                                 throw new RuntimeException("Cannot handle All that contains something else than Elements");
967                         }
968                         if (!indicator.getRestriction().single()) {
969                                 throw new RuntimeException("All indicator must have maxOccurs=1");
970                         }
971                         handle(parent, indicator, elements);
972                 }
973         }
974         
975         
976         protected void handle(SchemaObject parent, SchemaElement indicator, SchemaElement element, String baseRelationName) {
977                 Element localElement = element.getElement();
978                 if (localElement.getName() != null) {
979                         SchemaObject eObj = elements.get(localElement);
980                         QName refType = localElement.getType();
981                         if (refType != null)
982                                 handleIndicator(parent, indicator, element, null, RefType.Type, baseRelationName);
983                         else {
984                                 handleElement(eObj);
985                                 handleIndicator(parent, indicator, element, null, RefType.Element, baseRelationName);
986                         } 
987                 } else if (localElement.getRef() != null) {
988                         handleIndicator(parent, indicator,element, null, RefType.Reference, baseRelationName);
989                 }
990         }
991         
992         protected String getName(Element localElement) {
993                 if (localElement.getName() != null) {
994                         String refName = localElement.getName();
995                         return refName.replaceAll("\\.", "_");
996                 } else if (localElement.getRef() != null) {
997                         QName refType = localElement.getRef();
998                         if (refType != null)
999                                 return getName(refType);
1000                                 
1001                 }
1002                 return null;
1003         }
1004
1005         protected String getName(QName ref) {
1006                 String n = ref.getLocalPart();
1007                 return n.replaceAll("\\.", "_");
1008         }
1009         
1010         protected String getName(Attribute ref) {
1011                 String n = ref.getName();
1012                 if (n != null)
1013                         return n.replaceAll("\\.", "_");
1014                 else
1015                         return null;
1016         }
1017         
1018         protected String getChoiceName(List<SchemaElement> elements) {
1019                 if (elements.size() == 1) {
1020                         return null;
1021                 }
1022                 else if (elements.size() > 0 && elements.size() <= 3) {
1023                         List<String> names = new ArrayList<String>();
1024                         for (SchemaElement e : elements) {
1025                                 String name = getName(e.getElement());
1026                                 if (name != null)
1027                                         names.add(name);
1028                         }
1029                         String name = "";
1030                         for (int i = 0; i < names.size(); i++) {
1031                                 if (i == 0)
1032                                         name = names.get(i);
1033                                 else
1034                                         name += "Or"+names.get(i);
1035                         }
1036                         return name;
1037                 }
1038                 else {
1039                         return "SubElement";
1040                 }
1041         }
1042                 
1043         protected void handle(SchemaObject parent, Attribute attribute) {
1044                 component.handle(parent, attribute);
1045         }
1046         protected void handle(SchemaObject parent, AttributeGroup attribute) {
1047                 component.handle(parent, attribute);
1048         }
1049         protected void handle(SchemaObject parent, NamedGroup attribute){
1050                 component.handle(parent, attribute);
1051         };
1052         
1053         protected void handleSimpleType(SchemaObject parent, SchemaObject simpleType) {
1054                 component.handleSimpleType(parent, simpleType);
1055         }
1056         
1057         
1058         
1059         protected void handleComplexTypeExtension(SchemaObject complexTypeObj) {
1060                 ComplexType complexType = complexTypeObj.getComplexType();
1061                 if (complexType != null) {
1062                         if (complexType.getChoice() != null)
1063                                 handle(complexTypeObj, complexType.getChoice(), SchemaElement.ElementType.CHOICE);
1064                         if (complexType.getSequence() != null)
1065                                 handle(complexTypeObj, complexType.getSequence(), SchemaElement.ElementType.SEQUENCE);
1066                         if (complexType.getAll() != null)
1067                                 handle(complexTypeObj, complexType.getAll(), SchemaElement.ElementType.ALL);
1068                         if (complexType.getGroup() != null)
1069                                 throw new RuntimeException("Groups not supported");
1070                         ComplexContent complexContent = complexType.getComplexContent();
1071                         if (complexContent != null) {
1072                                 ExtensionType extensionType = complexContent.getExtension();
1073                                 if (extensionType != null) {
1074                                         if (extensionType.getChoice() != null) {
1075                                                 handle(complexTypeObj, extensionType.getChoice(), SchemaElement.ElementType.CHOICE);
1076                                         }
1077                                         if (extensionType.getSequence()!= null) {
1078                                                 handle(complexTypeObj, extensionType.getSequence(), SchemaElement.ElementType.SEQUENCE);
1079                                         }
1080                                         if (extensionType.getAll()!= null) {
1081                                                 handle(complexTypeObj, extensionType.getAll(), SchemaElement.ElementType.ALL);
1082                                         }
1083                                         if (extensionType.getGroup() != null) {
1084                                                 throw new RuntimeException("Groups not supported");
1085                                                 //handle(complexTypeObj, extensionType.getGroup(), SchemaElement.ElementType.GROUP_REF);
1086                                         }
1087                                 }
1088                         }
1089 //                      SimpleContent simpleContent = complexType.getSimpleContent();
1090 //                      if (simpleContent != null) {
1091 //                              ExtensionType extensionType = simpleContent.getExtension();
1092 //                      }
1093                 }
1094         }
1095         
1096         
1097         public boolean isElementRef(String ref) {
1098                 return elementName.containsKey(ref);
1099         }
1100         
1101         public boolean isComplexTypeRef(String ref) {
1102                 return complexTypeName.containsKey(ref);
1103         }
1104         
1105         public boolean isSimpleTypeRef(String ref) {
1106                 return simpleTypeName.containsKey(ref);
1107         }
1108         
1109         public IDProvider getIDProvider(Element element) {
1110                 List<IDProvider> idProviders = new ArrayList<IDProvider>(2);
1111                 for (JAXBElement<?> e : configuration.getConversionRule()) {
1112                         if (e.getValue() instanceof IDProvider) {
1113                                 IDProvider ref = (IDProvider)e.getValue();
1114                                 org.simantics.xml.sax.configuration.Element element2 = ref.getElement();
1115                                 if (element2 != null) {
1116                                         if (element.getName().equals(element2.getName()))
1117                                                 idProviders.add(ref);
1118                                 }
1119                                 
1120                         }
1121                 }
1122                 if (idProviders.size() == 0)
1123                         return null;
1124                 if (idProviders.size() > 1)
1125                         throw new RuntimeException("Element " + element.getName() + " contains " + idProviders.size() + " id provider rules, only one is allowed.");
1126                 return idProviders.get(0);
1127         }
1128         
1129         public IDProvider getIDProvider(ComplexType complexType) {
1130                 List<IDProvider> idProviders = new ArrayList<IDProvider>(2);
1131                 for (JAXBElement<?> e : configuration.getConversionRule()) {
1132                         if (e.getValue() instanceof IDProvider) {
1133                                 IDProvider ref = (IDProvider)e.getValue();
1134                                 org.simantics.xml.sax.configuration.ComplexType complexType2 = ref.getComplexType();
1135                                 if (complexType2 != null) {
1136                                         if (complexType.getName().equals(complexType2.getName()))
1137                                                 idProviders.add(ref);
1138                                 }
1139
1140                         }
1141                 }
1142                 if (idProviders.size() == 0)
1143                         return null;
1144                 if (idProviders.size() > 1)
1145                         throw new RuntimeException("Element " + complexType.getName() + " contains " + idProviders.size() + " id provider rules, only one is allowed.");
1146                 return idProviders.get(0);
1147         }
1148         
1149         public List<IDReference> getIDReferences(Element element) {
1150                 List<IDReference> idReferences = new ArrayList<IDReference>(2);
1151                 for (JAXBElement<?> e : configuration.getConversionRule()) {
1152                         if (e.getValue() instanceof IDReference) {
1153                                 IDReference ref = (IDReference)e.getValue();
1154                                 org.simantics.xml.sax.configuration.Element element2 = ref.getElement();
1155                                 if (element2 != null) {
1156                                         if (element.getName().equals(element2.getName()))
1157                                                 idReferences.add(ref);
1158                                 }
1159                         }
1160                 }
1161                 return idReferences;
1162         }
1163         
1164         public List<IDReference> getIDReferences(ComplexType complexType) {
1165                 List<IDReference> idReferences = new ArrayList<IDReference>(2);
1166                 for (JAXBElement<?> e : configuration.getConversionRule()) {
1167                         if (e.getValue() instanceof IDReference) {
1168                                 IDReference ref = (IDReference)e.getValue();
1169                                 org.simantics.xml.sax.configuration.ComplexType complexType2 = ref.getComplexType();
1170                                 if (complexType2 != null) {
1171                                         if (complexType.getName().equals(complexType2.getName()))
1172                                                 idReferences.add(ref);
1173                                 }
1174                         }
1175                 }
1176                 return idReferences;
1177         }
1178         
1179         public UnrecognizedChildElement getUnknown(ComplexType complexType) {
1180                 for (JAXBElement<?> e : configuration.getConversionRule()) {
1181                         if (e.getValue() instanceof UnrecognizedChildElement) {
1182                                 UnrecognizedChildElement rule = (UnrecognizedChildElement)e.getValue();
1183                                 org.simantics.xml.sax.configuration.ComplexType complexType2 = rule.getComplexType();
1184                                 if (complexType2 != null) {
1185                                         if (complexType.getName().equals(complexType2.getName()))
1186                                                 return rule;
1187                                 }
1188                         }
1189                 }
1190                 return null;
1191         }
1192         
1193         public UnrecognizedChildElement getUnknown(Element element) {
1194                 for (JAXBElement<?> e : configuration.getConversionRule()) {
1195                         if (e.getValue() instanceof UnrecognizedChildElement) {
1196                                 UnrecognizedChildElement rule = (UnrecognizedChildElement)e.getValue();
1197                                 org.simantics.xml.sax.configuration.Element element2 = rule.getElement();
1198                                 if (element2 != null) {
1199                                         if (element.getName().equals(element2.getName()))
1200                                                 return rule;
1201                                 }
1202                         }
1203                 }
1204                 return null;
1205         }
1206         
1207         public Rename getRename(Attribute element) {
1208                 for (JAXBElement<?> e : configuration.getConversionRule()) {
1209                         if (e.getValue() instanceof Rename) {
1210                                 Rename rule = (Rename)e.getValue();
1211                                 Object ref = rule.getElementOrComplexTypeOrAttribute().get(0);
1212                                 if (!(ref instanceof org.simantics.xml.sax.configuration.Attribute))
1213                                         continue;
1214                                 org.simantics.xml.sax.configuration.Attribute element2 = (org.simantics.xml.sax.configuration.Attribute)ref;
1215                                 if (element2.getName().equals(element.getName())) {
1216                                         return rule;
1217                                 }
1218                         }
1219                 }
1220                 return null;
1221         }
1222         
1223         public Rename getRename(ComplexType element) {
1224                 for (JAXBElement<?> e : configuration.getConversionRule()) {
1225                         if (e.getValue() instanceof Rename) {
1226                                 Rename rule = (Rename)e.getValue();
1227                                 Object ref = rule.getElementOrComplexTypeOrAttribute().get(0);
1228                                 if (!(ref instanceof org.simantics.xml.sax.configuration.ComplexType))
1229                                         continue;
1230                                 org.simantics.xml.sax.configuration.ComplexType element2 = (org.simantics.xml.sax.configuration.ComplexType)ref;
1231                                 if (element2.getName().equals(element.getName())) {
1232                                         return rule;
1233                                 }
1234                         }
1235                 }
1236                 return null;
1237         }
1238         
1239         public Rename getRename(Element element) {
1240                 for (JAXBElement<?> e : configuration.getConversionRule()) {
1241                         if (e.getValue() instanceof Rename) {
1242                                 Rename rule = (Rename)e.getValue();
1243                                 Object ref = rule.getElementOrComplexTypeOrAttribute().get(0);
1244                                 if (!(ref instanceof org.simantics.xml.sax.configuration.Element))
1245                                         continue;
1246                                 org.simantics.xml.sax.configuration.Element element2 = (org.simantics.xml.sax.configuration.Element)ref;
1247                                 if (element2.getName().equals(element.getName())) {
1248                                         return rule;
1249                                 }
1250                         }
1251                 }
1252                 return null;
1253         }
1254          
1255         
1256         public boolean useOriginalList(SchemaObject parent, SchemaElement indicator, SchemaElement element,  boolean reference, String ref, QName refType) {
1257                 if (parent.getName() == null)
1258                         parent = parent.getParent();
1259                 if (parent.getName().contains("PipingNetworkSegment"))
1260                         System.out.println();
1261                 for (JAXBElement<?> e : configuration.getConversionRule()) {
1262                         if (e.getValue() instanceof OrderedChild) {
1263                                 OrderedChild oc = (OrderedChild)e.getValue();
1264                                 org.simantics.xml.sax.configuration.Element element2 = oc.getElement();
1265                                 org.simantics.xml.sax.configuration.ComplexType complexType = oc.getComplexType();
1266                                 org.simantics.xml.sax.configuration.Element child = oc.getChild();
1267                                 if (!oc.getType().equals("original"))
1268                                         continue;
1269                                 boolean match = false;
1270                                 if (element2 != null) {
1271                                         if (parent.getType() == ObjectType.ELEMENT && parent.getName().equals(element2.getName())) {
1272                                                 match = true;
1273                                         }
1274                                 } else if (complexType != null) {
1275                                         if (parent.getType() == ObjectType.COMPLEX_TYPE && parent.getName() != null && parent.getName().equals(complexType.getName())) {
1276                                                 match = true;
1277                                         }
1278                                         
1279                                 }
1280                                 if (match) {
1281                                         if (child != null) {
1282                                                 if (matchChild(child, ref, refType)) {
1283                                                         if (oc.getValue().equals("disable"))
1284                                                                 return false;
1285                                                         else return true;
1286                                                 }
1287                                         } else { 
1288                                                 if (oc.getValue().equals("disable"))
1289                                                         return false;
1290                                                 return true;
1291                                         }
1292                                         
1293                                 }
1294                         }
1295                 }
1296                 return indicator.order();
1297         }
1298         
1299         public boolean useElementList(SchemaObject parent, SchemaElement indicator, SchemaElement element,  boolean reference, String refName, QName refType) {
1300                 if (parent.getName() == null)
1301                         parent = parent.getParent();
1302                 if (parent.getName() == "PipingNetworkSegment")
1303                         System.out.println();
1304                 for (JAXBElement<?> e : configuration.getConversionRule()) {
1305                         if (e.getValue() instanceof OrderedChild) {
1306                                 OrderedChild oc = (OrderedChild)e.getValue();
1307                                 org.simantics.xml.sax.configuration.Element element2 = oc.getElement();
1308                                 org.simantics.xml.sax.configuration.ComplexType complexType = oc.getComplexType();
1309                                 org.simantics.xml.sax.configuration.Element child = oc.getChild();
1310                                 if (!oc.getType().equals("child"))
1311                                         continue;
1312                                 boolean match = false;
1313                                 if (element2 != null) {
1314                                         if (parent.getType() == ObjectType.ELEMENT && parent.getName().equals(element2.getName())) {
1315                                                 match = true;
1316                                         }
1317                                 } else if (complexType != null) {
1318                                         if (parent.getType() == ObjectType.COMPLEX_TYPE && parent.getName() != null && parent.getName().equals(complexType.getName())) {
1319                                                 match = true;
1320                                         }
1321                                         
1322                                 }
1323                                 if (match) {
1324                                         if (child != null) {
1325                                                 if (matchChild(child, refName, refType)) {
1326                                                         if (oc.getValue().equals("disable"))
1327                                                                 return false;
1328                                                         else return true;
1329                                                 }
1330                                         } else {
1331                                                 if (oc.getValue().equals("disable"))
1332                                                         return false;
1333                                                 return true;
1334                                         }
1335                                         
1336                                 }
1337                         }
1338                 }
1339                 return element.many() && element.order();
1340         }
1341         
1342         private boolean matchChild(org.simantics.xml.sax.configuration.Element child, String refName, QName refType) {
1343                 if (refType != null && refType.getLocalPart().equals(child.getName()))
1344                         return true;
1345                 if (refName != null && refName.equals(child.getName()))
1346                         return true;
1347                 return false;
1348         }
1349         
1350         public static class TypeEntry {
1351                 String l0Type;
1352                 String binding;
1353                 String javaType;
1354                 String defaultValue;
1355                 boolean id;
1356                 String getterPrefix;
1357                 String getterPostfix;
1358                 String stringPrefix;
1359                 String stringPostfix;
1360                 public TypeEntry(String l0Type, String binding, String javaType, String defaultValue, String getterPrefix, String getterPostfix, String stringPrefix, String stringPostfix) {
1361                         super();
1362                         this.l0Type = l0Type;
1363                         this.binding = binding;
1364                         this.javaType = javaType;
1365                         this.defaultValue = defaultValue;
1366                         this.id = false;
1367                         this.getterPrefix = getterPrefix;
1368                         this.getterPostfix = getterPostfix;
1369                         this.stringPrefix = stringPrefix;
1370                         this.stringPostfix = stringPostfix;
1371                 }
1372                 
1373                 public TypeEntry(String l0Type, String binding, String javaType, String defaultValue, String getterPrefix, String getterPostfix, String stringPrefix, String stringPostfix, boolean id) {
1374                         super();
1375                         this.l0Type = l0Type;
1376                         this.binding = binding;
1377                         this.javaType = javaType;
1378                         this.defaultValue = defaultValue;
1379                         this.id = id;
1380                         this.getterPrefix = getterPrefix;
1381                         this.getterPostfix = getterPostfix;
1382                         this.stringPrefix = stringPrefix;
1383                         this.stringPostfix = stringPostfix;
1384                 }
1385                 
1386                 public String getValueGetterMethod(String name) {
1387                         return getterPrefix + name + ".getValue()"+getterPostfix;
1388                 }
1389                 public String getValueGetter(String name) {
1390                         return getterPrefix + name+getterPostfix;
1391                 }
1392                 public String getValueGetter()
1393                 {
1394                         return getValueGetter("value");
1395                 }
1396                 
1397                 public String getToString(String name) {
1398                         return stringPrefix +"("+javaType+")"+name+stringPostfix;
1399                 }
1400                 
1401                 public String getElementToString(String name) {
1402                         return stringPrefix + name+stringPostfix;
1403                 }
1404                 
1405         }
1406         
1407         public enum InheritanceType{ComplexType,AtomicType,None};
1408         
1409         public static class Inheritance {
1410                 public String baseClass;
1411                 public String additionalClass;
1412                 public InheritanceType type;
1413                 public TypeEntry atomicType;
1414                 
1415                 public Inheritance(String baseClass) {
1416                         this.baseClass = baseClass;
1417                         this.type = InheritanceType.None;
1418                 }
1419         }
1420         
1421         public String getComplexTypePrefix() {
1422                 return component.getComplexTypePrefix();
1423         }
1424         public String getAttributeGroupPrefix() {
1425                 return component.getAttributeGroupPrefix();
1426         }
1427         public String getName(SchemaObject obj) {
1428                 return component.getName(obj);
1429         }
1430         public String getBaseClass(ObjectType type) {
1431                 return component.getBaseClass(type);
1432         }
1433         
1434         
1435         
1436         public Inheritance getInheritance(SchemaObject topLevelObj) {
1437                 Inheritance inheritance = null;
1438                 if (topLevelObj.getType() == ObjectType.ELEMENT) {
1439                         Element topLevelElement = topLevelObj.getElement();
1440                         inheritance = new Inheritance(getBaseClass(ObjectType.ELEMENT));
1441                         if (topLevelElement.getType() != null) {
1442                                 QName type = topLevelElement.getType();
1443                                 if (!type.getNamespaceURI().equals(SCHEMA_NS)) {
1444                                         SchemaObject obj = complexTypeName.get(type.getLocalPart());
1445                                         if (obj != null) {
1446                                                 inheritance.baseClass = getName(obj);
1447                                                 inheritance.type = InheritanceType.ComplexType;
1448                                         }
1449                                         else {
1450                                                 obj = simpleTypeName.get(type.getLocalPart());
1451                                                 if (obj != null)
1452                                                         getAtomicTypeInheritance(type, inheritance);
1453                                         }
1454                                 } else {
1455                                         TypeEntry entry = getTypeEntry(type);
1456                                         if (entry != null) {
1457                                                 inheritance.type = InheritanceType.AtomicType;
1458                                                 inheritance.atomicType = entry;
1459                                         }
1460                                 }
1461                         }
1462                         if (inheritance.type == InheritanceType.None) {
1463                                 QName type = getElementBase(topLevelElement);
1464                                 if (type != null) {
1465                                         if (!type.getNamespaceURI().equals(SCHEMA_NS)) {
1466                                                 SchemaObject obj = getWithName(type);
1467                                                 inheritance.baseClass = getName(obj);
1468                                                 inheritance.type = InheritanceType.ComplexType;
1469                                         } else {
1470                                                 TypeEntry entry = getTypeEntry(type);
1471                                                 if (entry != null) {
1472                                                         inheritance.type = InheritanceType.AtomicType;
1473                                                         inheritance.atomicType = entry;
1474                                                 }
1475                                         }
1476                                 }
1477                         }
1478                         if (inheritance.type == InheritanceType.None) {
1479                                 QName type = topLevelElement.getSubstitutionGroup();
1480                                 if (type != null) {
1481                                         if (!type.getNamespaceURI().equals(SCHEMA_NS)) {
1482                                                 SchemaObject obj = getWithName(type);
1483                                                 inheritance.baseClass = getName(obj);
1484                                                 inheritance.type = InheritanceType.ComplexType;
1485                                         } else {
1486                                                 TypeEntry entry = getTypeEntry(type);
1487                                                 if (entry != null) {
1488                                                         inheritance.type = InheritanceType.AtomicType;
1489                                                         inheritance.atomicType = entry;
1490                                                 }
1491                                         }
1492                                 }
1493                         }
1494                 } else if (topLevelObj.getType() == ObjectType.COMPLEX_TYPE) {
1495                         ComplexType complexType = topLevelObj.getComplexType();
1496                         QName type = getComplexTypeBase(complexType);
1497                         inheritance = new Inheritance(getBaseClass(ObjectType.COMPLEX_TYPE));
1498                         if (type != null && !type.getNamespaceURI().equals("http://www.w3.org/2001/XMLSchema")) {
1499                                 SchemaObject obj = complexTypeName.get(type.getLocalPart());
1500                                 if (obj != null) {
1501                                         inheritance.baseClass = getName(obj);
1502                                         inheritance.type = InheritanceType.ComplexType;
1503                                 }
1504                         }
1505                         SimpleContent simpleContent = complexType.getSimpleContent();
1506                         if (simpleContent != null) {
1507                                 ExtensionType extensionType = simpleContent.getExtension();
1508                                 if (extensionType != null) {
1509                                         type = extensionType.getBase();
1510                                         SchemaObject simpleType = getSimpleType(type);
1511                                         if (simpleType != null)
1512                                                 inheritance.additionalClass = getName(simpleType);
1513                                         getAtomicTypeInheritance(type, inheritance);
1514                                 }
1515                         }
1516                 }
1517                 
1518                 return inheritance;
1519         }       
1520         /**
1521          * Goes through chain of SimpleTypes until locates Atomic Type (type defined in XML schema). 
1522          * @param type
1523          * @param topLevelObj
1524          * @param inheritance
1525          */
1526         public void getAtomicTypeInheritance(QName type, Inheritance inheritance) {
1527                 if (!type.getNamespaceURI().equals(SCHEMA_NS)) {
1528                         SchemaObject obj = getSimpleType(type);
1529                         if (obj == null)
1530                                 throw new RuntimeException("Cannot locate SimpleType " + type.getLocalPart());
1531                         SimpleType simpleType = obj.getSimpleType();
1532                         type = getSimpleTypeBase(simpleType);
1533                         getAtomicTypeInheritance(type, inheritance);
1534                 } else {
1535                         TypeEntry entry = getTypeEntry(type);
1536                         if (entry != null) {
1537                                 inheritance.type = InheritanceType.AtomicType;
1538                                 inheritance.atomicType = entry;
1539                         }
1540                 }
1541         }
1542         
1543         public String getDefaultValue(QName atype) {
1544                 Map<String,TypeEntry> types = typeMap.get(atype.getNamespaceURI());
1545                 if (types == null)
1546                         return null;
1547                 TypeEntry entry =  types.get(atype.getLocalPart());
1548                 if (entry == null)
1549                         return null;
1550                 return entry.defaultValue;
1551         }
1552
1553 }