]> gerrit.simantics Code Review - simantics/interop.git/blob - org.simantics.xml.sax/src/org/simantics/xml/sax/SchemaConversionBase.java
049b08775cb915dfd28628851f28b38634966c11
[simantics/interop.git] / org.simantics.xml.sax / src / org / simantics / xml / sax / SchemaConversionBase.java
1 package org.simantics.xml.sax;
2
3 import java.util.ArrayDeque;
4 import java.util.ArrayList;
5 import java.util.Deque;
6 import java.util.HashMap;
7 import java.util.HashSet;
8 import java.util.List;
9 import java.util.Map;
10 import java.util.Set;
11
12 import javax.xml.bind.JAXBElement;
13 import javax.xml.namespace.QName;
14
15 import org.simantics.utils.datastructures.BijectionMap;
16 import org.simantics.xml.sax.SchemaElement.ElementType;
17 import org.simantics.xml.sax.SchemaObject.ObjectType;
18 import org.simantics.xml.sax.configuration.AttributeComposition;
19 import org.simantics.xml.sax.configuration.Configuration;
20 import org.simantics.xml.sax.configuration.IDProvider;
21 import org.simantics.xml.sax.configuration.IDReference;
22 import org.simantics.xml.sax.configuration.OrderedChild;
23 import org.simantics.xml.sax.configuration.Rename;
24 import org.simantics.xml.sax.configuration.UnrecognizedChildElement;
25 import org.w3._2001.xmlschema.All;
26 import org.w3._2001.xmlschema.Annotated;
27 import org.w3._2001.xmlschema.Any;
28 import org.w3._2001.xmlschema.Attribute;
29 import org.w3._2001.xmlschema.AttributeGroup;
30 import org.w3._2001.xmlschema.ComplexContent;
31 import org.w3._2001.xmlschema.ComplexType;
32 import org.w3._2001.xmlschema.Element;
33 import org.w3._2001.xmlschema.ExplicitGroup;
34 import org.w3._2001.xmlschema.ExtensionType;
35 import org.w3._2001.xmlschema.GroupRef;
36 import org.w3._2001.xmlschema.LocalElement;
37 import org.w3._2001.xmlschema.NamedAttributeGroup;
38 import org.w3._2001.xmlschema.NamedGroup;
39 import org.w3._2001.xmlschema.OpenAttrs;
40 import org.w3._2001.xmlschema.RealGroup;
41 import org.w3._2001.xmlschema.Restriction;
42 import org.w3._2001.xmlschema.Schema;
43 import org.w3._2001.xmlschema.SimpleContent;
44 import org.w3._2001.xmlschema.SimpleType;
45 import org.w3._2001.xmlschema.TopLevelAttribute;
46 import org.w3._2001.xmlschema.TopLevelComplexType;
47 import org.w3._2001.xmlschema.TopLevelElement;
48 import org.w3._2001.xmlschema.TopLevelSimpleType;
49 import org.w3._2001.xmlschema.Union;
50
51 public final class SchemaConversionBase {
52         
53         protected Schema schema;
54         protected SchemaConverter converter;
55         protected SchemaConversionComponent component;
56         protected Configuration configuration;
57         
58         public static final String SCHEMA_NS = "http://www.w3.org/2001/XMLSchema";
59         public static final String CONVERSION_NS = "http://www.simantics.org/Layer0";
60         
61         protected Map<String,Map<String,TypeEntry>> typeMap;
62         
63         protected String ontologyURI;
64         protected String className;
65         
66         public SchemaConversionBase(SchemaConverter converter, String ontologyUri, String className) {
67                 this.converter = converter;
68                 this.configuration = converter.getConfiguration();
69                 this.ontologyURI = ontologyUri;
70                 this.className = className;
71                 
72                 initTypes();
73         }
74         
75         protected void initTypes() {
76                 typeMap = new HashMap<String, Map<String,TypeEntry>>();
77                 Map<String,TypeEntry> schemaTypes = new HashMap<String, SchemaConversionBase.TypeEntry>();
78                 typeMap.put(SCHEMA_NS, schemaTypes);
79                 Map<String,TypeEntry> l0Types = new HashMap<String, SchemaConversionBase.TypeEntry>();
80                 typeMap.put(CONVERSION_NS, l0Types);
81                 
82                 schemaTypes.put("string",               new TypeEntry("L0.String",                      "Bindings.STRING", "java.lang.String", "","","","",""));
83                 schemaTypes.put("NMTOKEN",              new TypeEntry("L0.String",                      "Bindings.STRING", "java.lang.String", "","","","",""));
84                 schemaTypes.put("token",                new TypeEntry("L0.String",                      "Bindings.STRING", "java.lang.String", "","","","",""));
85                 schemaTypes.put("ID",                   new TypeEntry("L0.String",                      "Bindings.STRING", "java.lang.String", "","","","","",true));
86                 schemaTypes.put("IDREF",                new TypeEntry("L0.String",                      "Bindings.STRING", "java.lang.String", "","","","",""));
87                 schemaTypes.put("Name",                 new TypeEntry("L0.String",                      "Bindings.STRING", "java.lang.String", "","","","",""));
88                 schemaTypes.put("NCName",               new TypeEntry("L0.String",                      "Bindings.STRING", "java.lang.String", "","","","",""));
89                 schemaTypes.put("date",                 new TypeEntry("XML.Date",                       "org.simantics.xml.sax.base.datatypes.literal.Date.BINDING", "org.simantics.xml.sax.base.datatypes.literal.Date", "","org.simantics.xml.sax.base.datatypes.literal.Date.parseDate(",")","(",").toString()"));
90                 schemaTypes.put("time",                 new TypeEntry("XML.Time",                       "org.simantics.xml.sax.base.datatypes.literal.Time.BINDING", "org.simantics.xml.sax.base.datatypes.literal.Time", "","org.simantics.xml.sax.base.datatypes.literal.Time.parseTime(",")","(",").toString()"));
91                 schemaTypes.put("dateTime",             new TypeEntry("XML.DateTime",           "org.simantics.xml.sax.base.datatypes.literal.DateTime.BINDING", "org.simantics.xml.sax.base.datatypes.literal.DateTime", "","org.simantics.xml.sax.base.datatypes.literal.DateTime.parseDateTime(",")","(",").toString()"));
92                 schemaTypes.put("gYearMonth",   new TypeEntry("L0.String",                      "Bindings.STRING", "java.lang.String", "","","","",""));
93                 schemaTypes.put("gYear",                new TypeEntry("L0.String",                      "Bindings.STRING", "java.lang.String", "","","","",""));
94                 schemaTypes.put("gMonth",               new TypeEntry("L0.String",                      "Bindings.STRING", "java.lang.String", "","","","",""));
95                 schemaTypes.put("gMonthDay",    new TypeEntry("L0.String",                      "Bindings.STRING", "java.lang.String", "","","","",""));
96                 schemaTypes.put("anyURI",               new TypeEntry("L0.URI",                         "Bindings.STRING", "java.lang.String", "","","","",""));
97                 schemaTypes.put("double",               new TypeEntry("L0.Double",                      "Bindings.DOUBLE", "double", "java.lang.Double.NaN","java.lang.Double.parseDouble(",")","java.lang.Double.toString(",")"));
98                 schemaTypes.put("float",                new TypeEntry("L0.Float",                       "Bindings.FLOAT",  "float",  "java.lang.Float.NaN","java.lang.Float.parseFloat(",")","java.lang.Float.toString(",")"));
99                 schemaTypes.put("decimal",              new TypeEntry("L0.Double",                      "Bindings.DOUBLE", "double", "java.lang.Double.NaN","java.lang.Double.parseDouble(",")","java.lang.Double.toString(",")"));
100                 schemaTypes.put("boolean",              new TypeEntry("L0.Boolean",                     "Bindings.BOOLEAN", "boolean", "false","java.lang.Boolean.parseBoolean(",")","java.lang.Boolean.toString(",")"));
101                 schemaTypes.put("integer",              new TypeEntry("L0.Integer",             "Bindings.INTEGER", "int", "0","java.lang.Integer.parseInt(",")","java.lang.Integer.toString(",")"));
102                 schemaTypes.put("positiveInteger", new TypeEntry("L0.Integer",          "Bindings.INTEGER", "int", "0","java.lang.Integer.parseInt(",")","java.lang.Integer.toString(",")"));
103                 schemaTypes.put("nonPositiveInteger", new TypeEntry("L0.Integer",       "Bindings.INTEGER", "int", "0","java.lang.Integer.parseInt(",")","java.lang.Integer.toString(",")"));
104                 schemaTypes.put("nonNegativeInteger", new TypeEntry("L0.Integer",       "Bindings.INTEGER", "int", "0","java.lang.Integer.parseInt(",")","java.lang.Integer.toString(",")"));
105                 schemaTypes.put("negativeInteger", new TypeEntry("L0.Integer",          "Bindings.INTEGER", "int", "0","java.lang.Integer.parseInt(",")","java.lang.Integer.toString(",")"));
106                 schemaTypes.put("unsignedInt",  new TypeEntry("L0.Integer",             "Bindings.INTEGER", "int", "0","java.lang.Integer.parseInt(",")","java.lang.Integer.toString(",")"));
107                 schemaTypes.put("int",                  new TypeEntry("L0.Integer",                     "Bindings.INTEGER", "int", "0","java.lang.Integer.parseInt(",")","java.lang.Integer.toString(",")"));
108                 schemaTypes.put("short",                new TypeEntry("L0.Integer",                     "Bindings.INTEGER", "int", "0","java.lang.Integer.parseInt(",")","java.lang.Integer.toString(",")"));
109                 schemaTypes.put("unsignedShort",new TypeEntry("L0.Integer",                     "Bindings.INTEGER", "int", "0","java.lang.Integer.parseInt(",")","java.lang.Integer.toString(",")"));
110                 schemaTypes.put("byte",                 new TypeEntry("L0.Byte",                        "Bindings.BYTE", "byte", "0","java.lang.Byte.parseByte(",")","java.lang.Byte.toString(",")"));
111                 schemaTypes.put("unsignedByte", new TypeEntry("L0.Byte",                        "Bindings.BYTE", "byte", "0","java.lang.Byte.parseByte(",")","java.lang.Byte.toString(",")"));
112                 schemaTypes.put("long",                 new TypeEntry("L0.Long",                        "Bindings.LONG", "long", "0","java.lang.Long.parseLong(",")","java.lang.Long.toString(",")"));
113                 schemaTypes.put("unsignedLong", new TypeEntry("L0.Long",                        "Bindings.LONG", "long", "0","java.lang.Long.parseLong(",")","java.lang.Long.toString(",")"));
114                 schemaTypes.put("base64Binary", new TypeEntry("L0.ByteArray",           "Bindings.BYTE_ARRAY", "byte[]", "new byte[0]","java.util.Base64.getDecoder().decode(",".replaceAll(\"\\n\", \"\").getBytes(java.nio.charset.StandardCharsets.UTF_8))","java.util.Base64.getEncoder().encodeToString(",")"));
115                 
116                 l0Types.put("doubleArray",              new TypeEntry("L0.DoubleArray",  "Bindings.DOUBLE_ARRAY", "double[]", null,null,null,"java.lang.Double.toString(",")"));
117                 l0Types.put("stringArray",              new TypeEntry("L0.StringArray",  "Bindings.STRING_ARRAY", "string[]", null,null,null,"",""));
118         }
119         
120         protected TypeEntry getTypeEntry(QName type) {
121                 Map<String,TypeEntry> types = typeMap.get(type.getNamespaceURI());
122                 if (types == null)
123                         return null;
124                 TypeEntry entry = types.get(type.getLocalPart());
125                 return entry;
126         }
127         protected TypeEntry getTypeEntry(String type) {
128                 for (Map<String,TypeEntry> types : typeMap.values()) {
129                         TypeEntry entry = types.get(type);
130                         if (entry != null)
131                                 return entry;
132                 }
133                 return null;
134         }
135         
136         protected String getL0TypeFromPrimitiveType(QName primitiveType) {
137                 TypeEntry entry = getTypeEntry(primitiveType);
138                 if (entry == null)
139                         return null;
140                 return entry.l0Type;
141         }
142         
143         protected String getL0Type(QName primitiveType) {
144                 String type = getL0TypeFromPrimitiveType(primitiveType);
145                 if (type != null)
146                         return type;
147                 SchemaObject simpleTypeObj = simpleTypeName.get(primitiveType.getLocalPart());
148                 if (simpleTypeObj == null)
149                         return null;
150                 SimpleType simpleType = simpleTypeObj.getSimpleType();
151                 while (simpleType != null) {
152                         QName base = simpleType.getRestriction().getBase();
153                         if (base != null)
154                                 return getL0Type(base);
155                         simpleType = simpleType.getRestriction().getSimpleType();
156                 }
157                 return null;
158         }
159         
160         protected String getBindingFromPrimitiveType(QName primitiveType) {
161                 TypeEntry entry = getTypeEntry(primitiveType);
162                 if (entry == null)
163                         return null;
164                 return entry.binding;
165         }
166         
167         protected String getJavaTypeFromPrimitiveType(QName primitiveType) {
168                 TypeEntry entry = getTypeEntry(primitiveType);
169                 if (entry == null)
170                         return null;
171                 return entry.javaType;
172         }
173         
174         
175         public void init(Schema schema) {       
176                 this.schema = schema;
177                 
178                 preload();
179         }
180         
181         public void handle(SchemaConversionComponent component) {
182                 this.component = component;
183                 for (OpenAttrs attrs : schema.getSimpleTypeOrComplexTypeOrGroup()) {
184                         if (attrs instanceof TopLevelAttribute) {
185                                 handle((TopLevelAttribute)attrs);
186                                 
187                         } else if (attrs instanceof TopLevelComplexType) {
188                                 handleComplexType(complexTypes.get(attrs));
189                         } else if (attrs instanceof TopLevelElement) {
190                                 handleElement(elements.get(attrs));
191                         } else if (attrs instanceof TopLevelSimpleType) {
192                                 handleSimpleType(simpleTypes.get(attrs));
193                         } else if (attrs instanceof NamedAttributeGroup) {
194                                 handle((NamedAttributeGroup)attrs);
195                         } else if (attrs instanceof NamedGroup) {
196                                 handle((NamedGroup)attrs);
197                         } else {
198                                 System.out.println(attrs.getClass().getName());
199                         }
200                 }
201         }
202         
203         private Map<String,SchemaObject> elementName = new HashMap<>();
204         private Map<String,SchemaObject> complexTypeName = new HashMap<>();
205         private Map<String,SchemaObject> simpleTypeName = new HashMap<>();
206         private Map<String,SchemaObject> modelGroupName = new HashMap<>();
207         private Map<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(this,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(this,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(this,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(this,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(this,object,e.getComplexType()));
452                                 if (e.getSimpleType() != null)
453                                         stack.push(new SchemaObject(this,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(this,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(this,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, String baseRelationName) {
773                 component.handleIndicator(parent, indicator, element, refName, refType, baseRelationName);
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                 // Generate combined relation
781                 String baseRelationName = null;
782                 if (indicator.getType() == SchemaElement.ElementType.CHOICE) {
783                         String name = getChoiceName(elements);
784                         if (name != null)
785                                 baseRelationName = component.handleChoice(parent, indicator, elements, name);
786                 }
787                 
788                 if (indicator.getType() == SchemaElement.ElementType.SEQUENCE || indicator.getType() == SchemaElement.ElementType.CHOICE) {
789                         for (SchemaElement e : elements) {
790                                 handle(parent, indicator, e, baseRelationName);
791                         }
792                 }
793         }
794         
795         protected void handle(SchemaObject parent, ExplicitGroup eg, SchemaElement.ElementType indicator) {
796                 handle(parent, new SchemaElement(eg, indicator));
797         }
798         
799         protected void handle(SchemaObject parent, GroupRef eg, SchemaElement.ElementType indicator) {
800                 handle(parent, new SchemaElement(eg, indicator));
801         }
802         
803         protected void handle(SchemaObject parent, SchemaElement indicator) {
804                 
805                 
806                 List<SchemaElement> elements = new ArrayList<SchemaElement>();
807                 List<SchemaElement> choices = new ArrayList<SchemaElement>();
808                 List<SchemaElement> sequences = new ArrayList<SchemaElement>();
809                 List<SchemaElement> alls = new ArrayList<SchemaElement>();
810                 List<SchemaElement> anys = new ArrayList<SchemaElement>();
811                 List<SchemaElement> groups = new ArrayList<SchemaElement>();
812                 
813                 for (Object o : indicator.getGroup().getParticle()) {
814                         if (o instanceof JAXBElement<?>) {
815                                 JAXBElement<?> element = (JAXBElement<?>)o;
816                                 Object elemValue = element.getValue();
817                                 if (elemValue instanceof LocalElement) {
818                                         LocalElement localElement = (LocalElement)elemValue;
819                                         elements.add(new SchemaElement(indicator,localElement, ElementType.ELEMENT));
820                                 } else if (elemValue instanceof All) {
821                                         alls.add(new SchemaElement(indicator,(All)elemValue, ElementType.ALL));
822                                 } else if (elemValue instanceof ExplicitGroup) {
823                                         QName qname = element.getName();
824                                         if ("choice".equals(qname.getLocalPart())) {
825                                                 choices.add(new SchemaElement(indicator,(ExplicitGroup)elemValue, ElementType.CHOICE));
826                                         } else if ("sequence".equals(qname.getLocalPart())) {
827                                                 sequences.add(new SchemaElement(indicator,(ExplicitGroup)elemValue, ElementType.SEQUENCE));
828                                         }
829                                 } else if (elemValue instanceof RealGroup) {
830                                         if (elemValue instanceof GroupRef) {
831                                                 groups.add(new SchemaElement(indicator,(GroupRef)elemValue, ElementType.GROUP_REF));
832                                         } else if (elemValue instanceof NamedGroup) {
833                                                 groups.add(new SchemaElement(indicator,(NamedGroup)elemValue, ElementType.NAMED_GROUP));
834                                         } else {
835                                                 throw new RuntimeException("Unknown ExplicitGroup element " + elemValue.getClass().getName());
836                                         }
837                                 } else {
838                                         throw new RuntimeException("Unknown ExplicitGroup element " + elemValue.getClass().getName());
839                                 }
840                         } else if (o instanceof Any){
841                                 anys.add(new SchemaElement(indicator,(Any)o, ElementType.ANY));
842                         } else {
843                                 throw new RuntimeException("Unknown ExplicitGroup reference " + o.getClass().getName());
844                         }
845                 }
846                 
847                 if (elements.size() == 0 && choices.size() == 0 && sequences.size() == 0 && alls.size() == 0 && anys.size() == 0 && groups.size() == 0) {
848                         return;
849                 }
850                 
851                 if (indicator.getType() == SchemaElement.ElementType.SEQUENCE) {
852                         if (indicator.getRestriction().single()) {
853                                 if (elements.size() > 0) {
854                                         for (SchemaElement e : sequences) {
855                                                 handle(parent, e);
856                                         }
857                                         for (SchemaElement c : choices) {
858                                                 handle(parent, c);
859                                         }
860                                         
861                                         for (SchemaElement c : alls) {
862                                                 handle(parent, c);
863                                         }
864                                         
865                                         for (SchemaElement c : groups) {
866                                                 handle(parent, c);
867                                         }
868                                         handle(parent, indicator, elements);
869                                         for (SchemaElement a : anys) {
870                                                 handleIndicator(parent, indicator, a);
871                                         }
872                                 } else {
873                                         if (sequences.size() > 0) {
874                                                 throw new RuntimeException("Cannot handle Sequence with inner Sequences");
875                                         }
876                                         for (SchemaElement c : choices) {
877                                                 handle(parent, c);
878                                         }
879                                         for (SchemaElement a : anys) {
880                                                 handleIndicator(parent, indicator, a);
881                                         }
882                                         for (SchemaElement c : groups) {
883                                                 handle(parent, c);
884                                         }
885                                 }
886                         } else {
887                                 if (choices.size() == 1 && sequences.size() == 0 && alls.size() == 0 && groups.size() == 0) {
888                                         // special case: handle lone choice inside sequence with maxOccurs > 1 
889                                         SchemaElement choice = choices.get(0);
890                                         // move multiplicity restrictions to choice
891                                         if (indicator.getRestriction().max == -1 || (choice.getRestriction().max > 0 && indicator.getRestriction().max > choice.getRestriction().max))
892                                                 choice.getRestriction().max = indicator.getRestriction().max;
893                                         if (indicator.getRestriction().min == 0 || choice.getRestriction().min > indicator.getRestriction().min)
894                                                 choice.getRestriction().min = indicator.getRestriction().min;
895                                         handle(parent, choice, elements);
896                                         return;
897                                 }
898                                 if (sequences.size() > 0 || choices.size() > 0 || alls.size() > 0 || groups.size() > 0) {
899                                         throw new RuntimeException("Cannot handle Sequence with inner ExplicitGroups");
900                                 }
901                                 handle(parent, indicator, elements);
902                                 for (SchemaElement a : anys) {
903                                         handleIndicator(parent, indicator, a);
904                                 }
905                         }
906                 
907                 } else if (indicator.getType() == SchemaElement.ElementType.CHOICE){
908                         if (indicator.getRestriction().single()) {
909                                 if (sequences.size()> 0 || choices.size() > 0 || alls.size() > 0 || anys.size() > 0 || groups.size() > 0) {
910                                         throw new RuntimeException("Cannot handle Choice that contains something else than Elements");
911                                         //System.out.println("Cannot handle Choice that contains something else than Elements");
912                                         //return;
913                                 }
914                                 handle(parent, indicator, elements);
915                                 
916                         } else {
917                                 if (sequences.size() > 0 || choices.size() > 0 || alls.size() > 0 || groups.size() > 0) {
918                                         throw new RuntimeException("Cannot handle Choice with inner ExplicitGroups");
919                                         //System.out.println("Cannot handle Choice with inner ExplicitGroups");
920                                         //return;
921                                 }
922                                 handle(parent, indicator,  elements);
923                                 for (SchemaElement a : anys) {
924                                         handleIndicator(parent, indicator, a);
925                                 }
926                         }
927                 } else if (indicator.getType() == ElementType.ALL) {
928                         if (sequences.size()> 0 || choices.size() > 0 || alls.size() > 0 || anys.size() > 0  || groups.size() > 0) {
929                                 throw new RuntimeException("Cannot handle All that contains something else than Elements");
930                         }
931                         if (!indicator.getRestriction().single()) {
932                                 throw new RuntimeException("All indicator must have maxOccurs=1");
933                         }
934                         handle(parent, indicator, elements);
935                 }
936         }
937         
938         
939         protected void handle(SchemaObject parent, SchemaElement indicator, SchemaElement element, String baseRelationName) {
940                 Element localElement = element.getElement();
941                 if (localElement.getName() != null) {
942                         SchemaObject eObj = elements.get(localElement);
943                         QName refType = localElement.getType();
944                         if (refType != null)
945                                 handleIndicator(parent, indicator, element, null, RefType.Type, baseRelationName);
946                         else {
947                                 handleElement(eObj);
948                                 handleIndicator(parent, indicator, element, null, RefType.Element, baseRelationName);
949                         } 
950                 } else if (localElement.getRef() != null) {
951                         handleIndicator(parent, indicator,element, null, RefType.Reference, baseRelationName);
952                 }
953         }
954         
955         protected String getName(Element localElement) {
956                 if (localElement.getName() != null) {
957                         String refName = localElement.getName();
958                         return refName.replaceAll("\\.", "_");
959                 } else if (localElement.getRef() != null) {
960                         QName refType = localElement.getRef();
961                         if (refType != null)
962                                 return getName(refType);
963                                 
964                 }
965                 return null;
966         }
967
968         protected String getName(QName ref) {
969                 String n = ref.getLocalPart();
970                 return n.replaceAll("\\.", "_");
971         }
972         
973         protected String getName(Attribute ref) {
974                 String n = ref.getName();
975                 if (n != null)
976                         return n.replaceAll("\\.", "_");
977                 else
978                         return null;
979         }
980         
981         protected String getChoiceName(List<SchemaElement> elements) {
982                 if (elements.size() == 1) {
983                         return null;
984                 }
985                 else if (elements.size() > 0 && elements.size() <= 3) {
986                         List<String> names = new ArrayList<String>();
987                         for (SchemaElement e : elements) {
988                                 String name = getName(e.getElement());
989                                 if (name != null)
990                                         names.add(name);
991                         }
992                         String name = "";
993                         for (int i = 0; i < names.size(); i++) {
994                                 if (i == 0)
995                                         name = names.get(i);
996                                 else
997                                         name += "Or"+names.get(i);
998                         }
999                         return name;
1000                 }
1001                 else {
1002                         return "SubElement";
1003                 }
1004         }
1005                 
1006         protected void handle(SchemaObject parent, Attribute attribute) {
1007                 component.handle(parent, attribute);
1008         }
1009         protected void handle(SchemaObject parent, AttributeGroup attribute) {
1010                 component.handle(parent, attribute);
1011         }
1012         protected void handle(SchemaObject parent, NamedGroup attribute){
1013                 component.handle(parent, attribute);
1014         };
1015         
1016         protected void handleSimpleType(SchemaObject parent, SchemaObject simpleType) {
1017                 component.handleSimpleType(parent, simpleType);
1018         }
1019         
1020         
1021         
1022         protected void handleComplexTypeExtension(SchemaObject complexTypeObj) {
1023                 ComplexType complexType = complexTypeObj.getComplexType();
1024                 if (complexType != null) {
1025                         if (complexType.getChoice() != null)
1026                                 handle(complexTypeObj, complexType.getChoice(), SchemaElement.ElementType.CHOICE);
1027                         if (complexType.getSequence() != null)
1028                                 handle(complexTypeObj, complexType.getSequence(), SchemaElement.ElementType.SEQUENCE);
1029                         if (complexType.getAll() != null)
1030                                 handle(complexTypeObj, complexType.getAll(), SchemaElement.ElementType.ALL);
1031                         if (complexType.getGroup() != null)
1032                                 throw new RuntimeException("Groups not supported");
1033                         ComplexContent complexContent = complexType.getComplexContent();
1034                         if (complexContent != null) {
1035                                 ExtensionType extensionType = complexContent.getExtension();
1036                                 if (extensionType != null) {
1037                                         if (extensionType.getChoice() != null) {
1038                                                 handle(complexTypeObj, extensionType.getChoice(), SchemaElement.ElementType.CHOICE);
1039                                         }
1040                                         if (extensionType.getSequence()!= null) {
1041                                                 handle(complexTypeObj, extensionType.getSequence(), SchemaElement.ElementType.SEQUENCE);
1042                                         }
1043                                         if (extensionType.getAll()!= null) {
1044                                                 handle(complexTypeObj, extensionType.getAll(), SchemaElement.ElementType.ALL);
1045                                         }
1046                                         if (extensionType.getGroup() != null) {
1047                                                 throw new RuntimeException("Groups not supported");
1048                                                 //handle(complexTypeObj, extensionType.getGroup(), SchemaElement.ElementType.GROUP_REF);
1049                                         }
1050                                 }
1051                         }
1052 //                      SimpleContent simpleContent = complexType.getSimpleContent();
1053 //                      if (simpleContent != null) {
1054 //                              ExtensionType extensionType = simpleContent.getExtension();
1055 //                      }
1056                 }
1057         }
1058         
1059         
1060         public boolean isElementRef(String ref) {
1061                 return elementName.containsKey(ref);
1062         }
1063         
1064         public boolean isComplexTypeRef(String ref) {
1065                 return complexTypeName.containsKey(ref);
1066         }
1067         
1068         public boolean isSimpleTypeRef(String ref) {
1069                 return simpleTypeName.containsKey(ref);
1070         }
1071         
1072         public IDProvider getIDProvider(Element element) {
1073                 List<IDProvider> idProviders = new ArrayList<IDProvider>(2);
1074                 for (JAXBElement<?> e : configuration.getConversionRule()) {
1075                         if (e.getValue() instanceof IDProvider) {
1076                                 IDProvider ref = (IDProvider)e.getValue();
1077                                 org.simantics.xml.sax.configuration.Element element2 = ref.getElement();
1078                                 if (element2 != null) {
1079                                         if (element.getName().equals(element2.getName()))
1080                                                 idProviders.add(ref);
1081                                 }
1082                                 
1083                         }
1084                 }
1085                 if (idProviders.size() == 0)
1086                         return null;
1087                 if (idProviders.size() > 1)
1088                         throw new RuntimeException("Element " + element.getName() + " contains " + idProviders.size() + " id provider rules, only one is allowed.");
1089                 return idProviders.get(0);
1090         }
1091         
1092         public IDProvider getIDProvider(ComplexType complexType) {
1093                 List<IDProvider> idProviders = new ArrayList<IDProvider>(2);
1094                 for (JAXBElement<?> e : configuration.getConversionRule()) {
1095                         if (e.getValue() instanceof IDProvider) {
1096                                 IDProvider ref = (IDProvider)e.getValue();
1097                                 org.simantics.xml.sax.configuration.ComplexType complexType2 = ref.getComplexType();
1098                                 if (complexType2 != null) {
1099                                         if (complexType.getName().equals(complexType2.getName()))
1100                                                 idProviders.add(ref);
1101                                 }
1102
1103                         }
1104                 }
1105                 if (idProviders.size() == 0)
1106                         return null;
1107                 if (idProviders.size() > 1)
1108                         throw new RuntimeException("Element " + complexType.getName() + " contains " + idProviders.size() + " id provider rules, only one is allowed.");
1109                 return idProviders.get(0);
1110         }
1111         
1112         public List<IDReference> getIDReferences(Element element) {
1113                 List<IDReference> idReferences = new ArrayList<IDReference>(2);
1114                 for (JAXBElement<?> e : configuration.getConversionRule()) {
1115                         if (e.getValue() instanceof IDReference) {
1116                                 IDReference ref = (IDReference)e.getValue();
1117                                 org.simantics.xml.sax.configuration.Element element2 = ref.getElement();
1118                                 if (element2 != null) {
1119                                         if (element.getName().equals(element2.getName()))
1120                                                 idReferences.add(ref);
1121                                 }
1122                         }
1123                 }
1124                 return idReferences;
1125         }
1126         
1127         public List<IDReference> getIDReferences(ComplexType complexType) {
1128                 List<IDReference> idReferences = new ArrayList<IDReference>(2);
1129                 for (JAXBElement<?> e : configuration.getConversionRule()) {
1130                         if (e.getValue() instanceof IDReference) {
1131                                 IDReference ref = (IDReference)e.getValue();
1132                                 org.simantics.xml.sax.configuration.ComplexType complexType2 = ref.getComplexType();
1133                                 if (complexType2 != null) {
1134                                         if (complexType.getName().equals(complexType2.getName()))
1135                                                 idReferences.add(ref);
1136                                 }
1137                         }
1138                 }
1139                 return idReferences;
1140         }
1141         
1142         public UnrecognizedChildElement getUnknown(ComplexType complexType) {
1143                 for (JAXBElement<?> e : configuration.getConversionRule()) {
1144                         if (e.getValue() instanceof UnrecognizedChildElement) {
1145                                 UnrecognizedChildElement rule = (UnrecognizedChildElement)e.getValue();
1146                                 org.simantics.xml.sax.configuration.ComplexType complexType2 = rule.getComplexType();
1147                                 if (complexType2 != null) {
1148                                         if (complexType.getName().equals(complexType2.getName()))
1149                                                 return rule;
1150                                 }
1151                         }
1152                 }
1153                 return null;
1154         }
1155         
1156         public UnrecognizedChildElement getUnknown(Element element) {
1157                 for (JAXBElement<?> e : configuration.getConversionRule()) {
1158                         if (e.getValue() instanceof UnrecognizedChildElement) {
1159                                 UnrecognizedChildElement rule = (UnrecognizedChildElement)e.getValue();
1160                                 org.simantics.xml.sax.configuration.Element element2 = rule.getElement();
1161                                 if (element2 != null) {
1162                                         if (element.getName().equals(element2.getName()))
1163                                                 return rule;
1164                                 }
1165                         }
1166                 }
1167                 return null;
1168         }
1169         
1170         public Rename getRename(Attribute element) {
1171                 for (JAXBElement<?> e : configuration.getConversionRule()) {
1172                         if (e.getValue() instanceof Rename) {
1173                                 Rename rule = (Rename)e.getValue();
1174                                 Object ref = rule.getElementOrComplexTypeOrAttribute().get(0);
1175                                 if (!(ref instanceof org.simantics.xml.sax.configuration.Attribute))
1176                                         continue;
1177                                 org.simantics.xml.sax.configuration.Attribute element2 = (org.simantics.xml.sax.configuration.Attribute)ref;
1178                                 if (element2.getName().equals(element.getName())) {
1179                                         return rule;
1180                                 }
1181                         }
1182                 }
1183                 return null;
1184         }
1185         
1186         public Rename getRename(ComplexType element) {
1187                 for (JAXBElement<?> e : configuration.getConversionRule()) {
1188                         if (e.getValue() instanceof Rename) {
1189                                 Rename rule = (Rename)e.getValue();
1190                                 Object ref = rule.getElementOrComplexTypeOrAttribute().get(0);
1191                                 if (!(ref instanceof org.simantics.xml.sax.configuration.ComplexType))
1192                                         continue;
1193                                 org.simantics.xml.sax.configuration.ComplexType element2 = (org.simantics.xml.sax.configuration.ComplexType)ref;
1194                                 if (element2.getName().equals(element.getName())) {
1195                                         return rule;
1196                                 }
1197                         }
1198                 }
1199                 return null;
1200         }
1201         
1202         public Rename getRename(Element element) {
1203                 for (JAXBElement<?> e : configuration.getConversionRule()) {
1204                         if (e.getValue() instanceof Rename) {
1205                                 Rename rule = (Rename)e.getValue();
1206                                 Object ref = rule.getElementOrComplexTypeOrAttribute().get(0);
1207                                 if (!(ref instanceof org.simantics.xml.sax.configuration.Element))
1208                                         continue;
1209                                 org.simantics.xml.sax.configuration.Element element2 = (org.simantics.xml.sax.configuration.Element)ref;
1210                                 if (element2.getName().equals(element.getName())) {
1211                                         return rule;
1212                                 }
1213                         }
1214                 }
1215                 return null;
1216         }
1217          
1218         
1219         public boolean useOriginalList(SchemaObject parent, SchemaElement indicator, SchemaElement element,  boolean reference, String ref, QName refType) {
1220                 if (parent.getName() == null)
1221                         parent = parent.getParent();
1222                 if (parent.getName().contains("PipingNetworkSegment"))
1223                         System.out.println();
1224                 for (JAXBElement<?> e : configuration.getConversionRule()) {
1225                         if (e.getValue() instanceof OrderedChild) {
1226                                 OrderedChild oc = (OrderedChild)e.getValue();
1227                                 org.simantics.xml.sax.configuration.Element element2 = oc.getElement();
1228                                 org.simantics.xml.sax.configuration.ComplexType complexType = oc.getComplexType();
1229                                 org.simantics.xml.sax.configuration.Element child = oc.getChild();
1230                                 if (!oc.getType().equals("original"))
1231                                         continue;
1232                                 boolean match = false;
1233                                 if (element2 != null) {
1234                                         if (parent.getType() == ObjectType.ELEMENT && parent.getName().equals(element2.getName())) {
1235                                                 match = true;
1236                                         }
1237                                 } else if (complexType != null) {
1238                                         if (parent.getType() == ObjectType.COMPLEX_TYPE && parent.getName() != null && parent.getName().equals(complexType.getName())) {
1239                                                 match = true;
1240                                         }
1241                                         
1242                                 }
1243                                 if (match) {
1244                                         if (child != null) {
1245                                                 if (matchChild(child, ref, refType)) {
1246                                                         if (oc.getValue().equals("disable"))
1247                                                                 return false;
1248                                                         else return true;
1249                                                 }
1250                                         } else { 
1251                                                 if (oc.getValue().equals("disable"))
1252                                                         return false;
1253                                                 return true;
1254                                         }
1255                                         
1256                                 }
1257                         }
1258                 }
1259                 return indicator.order();
1260         }
1261         
1262         public boolean useElementList(SchemaObject parent, SchemaElement indicator, SchemaElement element,  boolean reference, String refName, QName refType) {
1263                 if (parent.getName() == null)
1264                         parent = parent.getParent();
1265                 if (parent.getName() == "PipingNetworkSegment")
1266                         System.out.println();
1267                 for (JAXBElement<?> e : configuration.getConversionRule()) {
1268                         if (e.getValue() instanceof OrderedChild) {
1269                                 OrderedChild oc = (OrderedChild)e.getValue();
1270                                 org.simantics.xml.sax.configuration.Element element2 = oc.getElement();
1271                                 org.simantics.xml.sax.configuration.ComplexType complexType = oc.getComplexType();
1272                                 org.simantics.xml.sax.configuration.Element child = oc.getChild();
1273                                 if (!oc.getType().equals("child"))
1274                                         continue;
1275                                 boolean match = false;
1276                                 if (element2 != null) {
1277                                         if (parent.getType() == ObjectType.ELEMENT && parent.getName().equals(element2.getName())) {
1278                                                 match = true;
1279                                         }
1280                                 } else if (complexType != null) {
1281                                         if (parent.getType() == ObjectType.COMPLEX_TYPE && parent.getName() != null && parent.getName().equals(complexType.getName())) {
1282                                                 match = true;
1283                                         }
1284                                         
1285                                 }
1286                                 if (match) {
1287                                         if (child != null) {
1288                                                 if (matchChild(child, refName, refType)) {
1289                                                         if (oc.getValue().equals("disable"))
1290                                                                 return false;
1291                                                         else return true;
1292                                                 }
1293                                         } else {
1294                                                 if (oc.getValue().equals("disable"))
1295                                                         return false;
1296                                                 return true;
1297                                         }
1298                                         
1299                                 }
1300                         }
1301                 }
1302                 return element.many() && element.order();
1303         }
1304         
1305         private boolean matchChild(org.simantics.xml.sax.configuration.Element child, String refName, QName refType) {
1306                 if (refType != null && refType.getLocalPart().equals(child.getName()))
1307                         return true;
1308                 if (refName != null && refName.equals(child.getName()))
1309                         return true;
1310                 return false;
1311         }
1312         
1313         public static class TypeEntry {
1314                 String l0Type;
1315                 String binding;
1316                 String javaType;
1317                 String defaultValue;
1318                 boolean id;
1319                 String getterPrefix;
1320                 String getterPostfix;
1321                 String stringPrefix;
1322                 String stringPostfix;
1323                 public TypeEntry(String l0Type, String binding, String javaType, String defaultValue, String getterPrefix, String getterPostfix, String stringPrefix, String stringPostfix) {
1324                         super();
1325                         this.l0Type = l0Type;
1326                         this.binding = binding;
1327                         this.javaType = javaType;
1328                         this.defaultValue = defaultValue;
1329                         this.id = false;
1330                         this.getterPrefix = getterPrefix;
1331                         this.getterPostfix = getterPostfix;
1332                         this.stringPrefix = stringPrefix;
1333                         this.stringPostfix = stringPostfix;
1334                 }
1335                 
1336                 public TypeEntry(String l0Type, String binding, String javaType, String defaultValue, String getterPrefix, String getterPostfix, String stringPrefix, String stringPostfix, boolean id) {
1337                         super();
1338                         this.l0Type = l0Type;
1339                         this.binding = binding;
1340                         this.javaType = javaType;
1341                         this.defaultValue = defaultValue;
1342                         this.id = id;
1343                         this.getterPrefix = getterPrefix;
1344                         this.getterPostfix = getterPostfix;
1345                         this.stringPrefix = stringPrefix;
1346                         this.stringPostfix = stringPostfix;
1347                 }
1348                 
1349                 public String getValueGetterMethod(String name) {
1350                         return getterPrefix + name + ".getValue()"+getterPostfix;
1351                 }
1352                 public String getValueGetter(String name) {
1353                         return getterPrefix + name+getterPostfix;
1354                 }
1355                 public String getValueGetter()
1356                 {
1357                         return getValueGetter("value");
1358                 }
1359                 
1360                 public String getToString(String name) {
1361                         return stringPrefix +"("+javaType+")"+name+stringPostfix;
1362                 }
1363                 
1364                 public String getElementToString(String name) {
1365                         return stringPrefix + name+stringPostfix;
1366                 }
1367                 
1368         }
1369         
1370         public enum InheritanceType{ComplexType,AtomicType,None};
1371         
1372         public static class Inheritance {
1373                 public String baseClass;
1374                 public String additionalClass;
1375                 public InheritanceType type;
1376                 public TypeEntry atomicType;
1377                 
1378                 public Inheritance(String baseClass) {
1379                         this.baseClass = baseClass;
1380                         this.type = InheritanceType.None;
1381                 }
1382         }
1383         
1384         public String getComplexTypePrefix() {
1385                 return component.getComplexTypePrefix();
1386         }
1387         public String getAttributeGroupPrefix() {
1388                 return component.getAttributeGroupPrefix();
1389         }
1390         public String getName(SchemaObject obj) {
1391                 return component.getName(obj);
1392         }
1393         public String getBaseClass(ObjectType type) {
1394                 return component.getBaseClass(type);
1395         }
1396         
1397         
1398         
1399         public Inheritance getInheritance(SchemaObject topLevelObj) {
1400                 Inheritance inheritance = null;
1401                 if (topLevelObj.getType() == ObjectType.ELEMENT) {
1402                         Element topLevelElement = topLevelObj.getElement();
1403                         inheritance = new Inheritance(getBaseClass(ObjectType.ELEMENT));
1404                         if (topLevelElement.getType() != null) {
1405                                 QName type = topLevelElement.getType();
1406                                 if (!type.getNamespaceURI().equals(SCHEMA_NS)) {
1407                                         SchemaObject obj = complexTypeName.get(type.getLocalPart());
1408                                         if (obj != null) {
1409                                                 inheritance.baseClass = getName(obj);
1410                                                 inheritance.type = InheritanceType.ComplexType;
1411                                         }
1412                                         else {
1413                                                 obj = simpleTypeName.get(type.getLocalPart());
1414                                                 if (obj != null)
1415                                                         getAtomicTypeInheritance(type, inheritance);
1416                                         }
1417                                 } else {
1418                                         TypeEntry entry = getTypeEntry(type);
1419                                         if (entry != null) {
1420                                                 inheritance.type = InheritanceType.AtomicType;
1421                                                 inheritance.atomicType = entry;
1422                                         }
1423                                 }
1424                         }
1425                         if (inheritance.type == InheritanceType.None) {
1426                                 QName type = getElementBase(topLevelElement);
1427                                 if (type != null) {
1428                                         if (!type.getNamespaceURI().equals(SCHEMA_NS)) {
1429                                                 SchemaObject obj = getWithName(type);
1430                                                 inheritance.baseClass = getName(obj);
1431                                                 inheritance.type = InheritanceType.ComplexType;
1432                                         } else {
1433                                                 TypeEntry entry = getTypeEntry(type);
1434                                                 if (entry != null) {
1435                                                         inheritance.type = InheritanceType.AtomicType;
1436                                                         inheritance.atomicType = entry;
1437                                                 }
1438                                         }
1439                                 }
1440                         }
1441                         if (inheritance.type == InheritanceType.None) {
1442                                 QName type = topLevelElement.getSubstitutionGroup();
1443                                 if (type != null) {
1444                                         if (!type.getNamespaceURI().equals(SCHEMA_NS)) {
1445                                                 SchemaObject obj = getWithName(type);
1446                                                 inheritance.baseClass = getName(obj);
1447                                                 inheritance.type = InheritanceType.ComplexType;
1448                                         } else {
1449                                                 TypeEntry entry = getTypeEntry(type);
1450                                                 if (entry != null) {
1451                                                         inheritance.type = InheritanceType.AtomicType;
1452                                                         inheritance.atomicType = entry;
1453                                                 }
1454                                         }
1455                                 }
1456                         }
1457                 } else if (topLevelObj.getType() == ObjectType.COMPLEX_TYPE) {
1458                         ComplexType complexType = topLevelObj.getComplexType();
1459                         QName type = getComplexTypeBase(complexType);
1460                         inheritance = new Inheritance(getBaseClass(ObjectType.COMPLEX_TYPE));
1461                         if (type != null && !type.getNamespaceURI().equals("http://www.w3.org/2001/XMLSchema")) {
1462                                 SchemaObject obj = complexTypeName.get(type.getLocalPart());
1463                                 if (obj != null) {
1464                                         inheritance.baseClass = getName(obj);
1465                                         inheritance.type = InheritanceType.ComplexType;
1466                                 }
1467                         }
1468                         SimpleContent simpleContent = complexType.getSimpleContent();
1469                         if (simpleContent != null) {
1470                                 ExtensionType extensionType = simpleContent.getExtension();
1471                                 if (extensionType != null) {
1472                                         type = extensionType.getBase();
1473                                         SchemaObject simpleType = getSimpleType(type);
1474                                         if (simpleType != null)
1475                                                 inheritance.additionalClass = getName(simpleType);
1476                                         getAtomicTypeInheritance(type, inheritance);
1477                                 }
1478                         }
1479                 }
1480                 
1481                 return inheritance;
1482         }       
1483         /**
1484          * Goes through chain of SimpleTypes until locates Atomic Type (type defined in XML schema). 
1485          * @param type
1486          * @param topLevelObj
1487          * @param inheritance
1488          */
1489         public void getAtomicTypeInheritance(QName type, Inheritance inheritance) {
1490                 if (!type.getNamespaceURI().equals(SCHEMA_NS)) {
1491                         SchemaObject obj = getSimpleType(type);
1492                         if (obj == null)
1493                                 throw new RuntimeException("Cannot locate SimpleType " + type.getLocalPart());
1494                         SimpleType simpleType = obj.getSimpleType();
1495                         type = getSimpleTypeBase(simpleType);
1496                         getAtomicTypeInheritance(type, inheritance);
1497                 } else {
1498                         TypeEntry entry = getTypeEntry(type);
1499                         if (entry != null) {
1500                                 inheritance.type = InheritanceType.AtomicType;
1501                                 inheritance.atomicType = entry;
1502                         }
1503                 }
1504         }
1505         
1506         public String getDefaultValue(QName atype) {
1507                 Map<String,TypeEntry> types = typeMap.get(atype.getNamespaceURI());
1508                 if (types == null)
1509                         return null;
1510                 TypeEntry entry =  types.get(atype.getLocalPart());
1511                 if (entry == null)
1512                         return null;
1513                 return entry.defaultValue;
1514         }
1515
1516 }