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