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