]> gerrit.simantics Code Review - simantics/interop.git/blob - org.simantics.xml.sax/src/org/simantics/xml/sax/SchemaConversionBase.java
cb0f7629f2ca38f28f16a7d9cc11313f6dc6444c
[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(element);
364                                 obj.setRename(getRename(element));
365                                 stack.push(obj);
366                         } else if (attrs instanceof ComplexType) {
367                                 ComplexType complexType = (ComplexType)attrs;
368                                 SchemaObject obj = new SchemaObject(complexType);
369                                 obj.setRename(getRename(complexType));
370                                 stack.push(obj);
371                         } else if (attrs instanceof SimpleType) {
372                                 SimpleType simpleType = (SimpleType)attrs;
373                                 SchemaObject obj = new SchemaObject(simpleType);
374                                 stack.push(obj);
375                         }  else if (attrs instanceof Attribute) {
376                                 // Attributes are not cached
377                         } else if (attrs instanceof AttributeGroup) {
378                                 // Attribute groups are not cached
379                         } else if (attrs instanceof NamedGroup) {
380                                 NamedGroup group = (NamedGroup)attrs;
381                                 SchemaObject obj = new SchemaObject(group);
382                                 stack.push(obj);
383                         } else {
384                                 System.out.println(attrs.getClass().getName());
385                         }
386                 }
387                 
388                 while (!stack.isEmpty()) {
389                         SchemaObject object = stack.pop();
390                         switch (object.getType()) {
391                         case COMPLEX_TYPE:{
392                                 ComplexType ct = object.getComplexType();
393                                 if (ct.getName() != null && ct.getName().length() > 0 && ct instanceof TopLevelComplexType)
394                                         complexTypeName.put(ct.getName(), object);
395                                 complexTypes.put(ct, object);
396                                 if (ct.getChoice() != null) {
397                                         preload(object,ct.getChoice(), stack);
398                                 }
399                                 if (ct.getSequence() != null) {
400                                         preload(object,ct.getSequence(), stack);
401                                 }
402                                 if (ct.getAll() != null) {
403                                         preload(object,ct.getAll(), stack);
404                                 }
405                                 if (ct.getGroup() != null)
406                                         throw new RuntimeException("Groups not supported");
407                                 if (ct.getComplexContent() != null) {
408                                         ComplexContent cc = ct.getComplexContent();
409                                         ExtensionType extensionType = cc.getExtension();
410                                         if (extensionType != null) {
411                                                 if (extensionType.getChoice() != null) {
412                                                         preload(object,extensionType.getChoice(), stack);
413                                                 }
414                                                 if (extensionType.getSequence()!= null) {
415                                                         preload(object,extensionType.getSequence(), stack);
416                                                 }
417                                                 if (extensionType.getAll()!= null) {
418                                                         preload(object,extensionType.getAll(), stack);
419                                                 }
420                                                 if (extensionType.getGroup() != null) {
421                                                         throw new RuntimeException("Groups not supported");
422                                                         //preload(object,extensionType.getGroup(), stack);
423                                                 }
424                                         }
425                                 }
426                                 if (ct.getSimpleContent() != null) {
427                                         SimpleContent cc = ct.getSimpleContent();
428                                         ExtensionType extensionType = cc.getExtension();
429                                         if (extensionType != null) {
430                                                 if (extensionType.getChoice() != null) {
431                                                         preload(object,extensionType.getChoice(), stack);
432                                                 }
433                                                 if (extensionType.getSequence()!= null) {
434                                                         preload(object,extensionType.getSequence(), stack);
435                                                 }
436                                                 if (extensionType.getAll()!= null) {
437                                                         preload(object,extensionType.getAll(), stack);
438                                                 }
439                                                 if (extensionType.getGroup() != null)
440                                                         throw new RuntimeException("Groups not supported");
441                                         }
442                                 }
443                                 break;
444                         } 
445                         case ELEMENT:{
446                                 Element e = object.getElement();
447                                 if (e instanceof TopLevelElement)
448                                         elementName.put(e.getName(), object);
449                                 elements.put(e, object);
450                                 if (e.getComplexType() != null)
451                                         stack.push(new SchemaObject(object,e.getComplexType()));
452                                 if (e.getSimpleType() != null)
453                                         stack.push(new SchemaObject(object,e.getSimpleType()));
454                                 break;
455                         } 
456                         case SIMPLE_TYPE:{
457                                 SimpleType e = object.getSimpleType();
458                                 if (e instanceof TopLevelSimpleType)
459                                         simpleTypeName.put(e.getName(), object);
460                                 simpleTypes.put(e, object);
461                                 break;
462                         } 
463                         case MODEL_GROUP:{
464                                 NamedGroup e = object.getModelGroup();
465                                 modelGroupName.put(e.getName(), object);
466                                 modelGroups.put(e, object);
467                                 break;
468                         }
469                         }
470                 } // while
471         }
472         
473         private void preload(SchemaObject parent,ExplicitGroup eg, Deque<SchemaObject> stack) {
474                 for (Object o : eg.getParticle()) {
475                         if (o instanceof JAXBElement<?>) {
476                                 JAXBElement<?> element = (JAXBElement<?>)o;
477                                 Object elemValue = element.getValue();
478                                 if (elemValue instanceof Element) {
479                                         SchemaObject obj = new SchemaObject(parent,(Element)elemValue);
480                                         obj.setRename(getRename((Element)elemValue));
481                                         stack.add(obj);
482                                 } else if (elemValue instanceof ExplicitGroup) {
483                                         preload(parent,(ExplicitGroup)elemValue, stack);
484                                 } else if (elemValue instanceof RealGroup) {
485                                         preload(parent,(RealGroup)elemValue, stack);
486                                 } else {
487                                         throw new RuntimeException("Unknown ExplicitGroup element " + elemValue.getClass().getName());
488                                 }
489                         } else if (o instanceof Any){
490                                 
491                         } else {
492                                 throw new RuntimeException("Unknown ExplicitGroup reference " + o.getClass().getName());
493                         }
494                 }
495         }
496         
497         private void preload(SchemaObject parent, RealGroup eg, Deque<SchemaObject> stack) {
498                 System.out.println(eg); 
499                 if (eg instanceof NamedGroup) {
500                         SchemaObject obj = new SchemaObject(parent,(NamedGroup)eg);
501                         stack.add(obj);
502                 }
503         }
504
505         
506         protected void handle(TopLevelAttribute topLevelAttribute) {
507                 handle(null, topLevelAttribute);
508         }
509         
510         protected void handleSimpleType(SchemaObject topLevelSimpleType) {
511                 handleSimpleType(null,topLevelSimpleType);
512         }
513         
514         protected void handle(NamedAttributeGroup namedAttributeGroup){
515                 handle(null, namedAttributeGroup);
516         }
517         
518         protected void handle(NamedGroup namedAttributeGroup){
519                 handle(null, namedAttributeGroup);
520         }
521         
522         protected QName getComplexTypeBase(ComplexType complexType) {
523                 if (complexType == null)
524                         return null;
525                 ComplexContent complexContent = complexType.getComplexContent();
526                 if (complexContent != null) {
527                         ExtensionType extensionType = complexContent.getExtension();
528                         if (extensionType != null) {
529                                 QName type = extensionType.getBase();
530                                 return type;
531                         }
532                 }
533                 return null;
534         }
535         
536         protected QName getSimpleTypeBase(SimpleType simpleType) {
537 //              if (simpleType == null)
538 //                      return null;
539 //              return simpleType.getRestriction().getBase();
540                 
541                 Restriction restriction = simpleType.getRestriction();
542                 if (restriction != null) {
543                         QName base = restriction.getBase();
544                         return base;
545                 } else if (simpleType.getId() != null) {
546                         throw new RuntimeException(simpleType.getName() + " restriction error");
547                 } else if (simpleType.getUnion() != null) {
548                         Union union = simpleType.getUnion();
549                         if (union.getMemberTypes().size() > 0) {
550                                 QName base = null;
551                                 for (QName type : union.getMemberTypes()) {
552                                         QName sType = null;
553                                         TypeEntry entry = getTypeEntry(type);
554                                         if (entry == null) {
555                                                 //SchemaObject obj = simpleTypeName.get(type.getLocalPart());
556                                                 SchemaObject obj = getSimpleType(type);
557                                                 if (obj == null)
558                                                         throw new RuntimeException(simpleType.getName() + " union has unresolved reference " + type.getLocalPart());
559                                                 sType = getSimpleTypeBase(obj.getSimpleType());
560                                         } else {
561                                                 sType = type;
562                                         }
563                                         if (base == null)
564                                                 base = sType;
565                                         else if (!base.equals(sType)) {
566                                                 //FIXME : throw new RuntimeException(simpleType.getName() + " union has incompatible member types");
567                                                 // fall back to string. 
568                                                 base = new QName(SCHEMA_NS, "string");
569                                                 
570                                         }
571                                 }
572                                 return base;
573                         } else {
574                                 if (union.getSimpleType().size() == 0)
575                                         throw new RuntimeException(simpleType.getName() + " union error");
576                                 for (SimpleType s : union.getSimpleType()) {
577                                         if (restriction == null)
578                                                 restriction = s.getRestriction();
579                                         else  {
580                                                 Restriction r = s.getRestriction();
581                                                 if (!r.getBase().equals(restriction.getBase())) {
582                                                         Inheritance rI = new Inheritance("");
583                                                         getAtomicTypeInheritance(r.getBase(), rI);
584                                                         Inheritance restI = new Inheritance("");
585                                                         getAtomicTypeInheritance(restriction.getBase(), restI);
586                                                         if (!rI.atomicType.l0Type.equals(restI.atomicType.l0Type))
587                                                                 throw new RuntimeException(simpleType.getName() + " union has incompatible restriction bases");
588                                                 }
589                                         }
590                                 }
591                                 QName base = restriction.getBase();
592                                 return base;
593                         }
594                 } else if (simpleType.getList() != null) {
595                         // FIXME: callers cannot get the information that we have a list.
596                         org.w3._2001.xmlschema.List list = simpleType.getList();
597                         return list.getItemType();
598                 } else {
599                         throw new RuntimeException(simpleType.getName() + " restriction error");
600                 }
601         }
602         
603         protected QName getElementBase(Element element) {
604                 ComplexType complexType = element.getComplexType();
605                 SimpleType simpleType = element.getSimpleType();
606                 if (complexType != null)
607                         return getComplexTypeBase(complexType);
608                 if (simpleType != null) {
609                         return getSimpleTypeBase(simpleType);
610                 }
611                 return null;
612         }
613         
614         private void handleAttributes(SchemaObject complexType, List<Annotated> attributeOrAttributeGroup) {
615                 //name = getComplexTypePrefix()+complexType.getName()
616                 
617                 Set<Annotated> handled = handleAttributeCompositions(complexType,attributeOrAttributeGroup);
618                 for (Annotated annotated : attributeOrAttributeGroup) {
619                         if (handled.contains(annotated))
620                                 continue;
621                         if (annotated instanceof Attribute) {
622                                 handle(complexType,(Attribute)annotated);
623                         } else if (annotated instanceof AttributeGroup){
624                                 handle(complexType,(AttributeGroup)annotated);
625                                 //comment("AttributeGroup " + ((AttributeGroup)annotated).getRef().getLocalPart());
626                         } else {
627                                 throw new RuntimeException();
628                         }
629                 }
630         }
631         
632         protected void handleAttributes(SchemaObject simpleTypeObj) {
633                 component.handleAttributes(simpleTypeObj);
634         }
635         
636         protected void handleExtensionAttributes(SchemaObject complexType) {
637                 ComplexContent complexContent = complexType.getComplexType().getComplexContent();
638                 if (complexContent != null) {
639                         ExtensionType extensionType = complexContent.getExtension();
640                         if (extensionType != null) {
641                                 handleAttributes(complexType, extensionType.getAttributeOrAttributeGroup());
642                         }
643                 }
644                 SimpleContent simpleContent = complexType.getComplexType().getSimpleContent();
645                 if (simpleContent != null) {
646                         ExtensionType extensionType = simpleContent.getExtension();
647                         if (extensionType != null) {
648                                 handleAttributes(complexType, extensionType.getAttributeOrAttributeGroup());
649                         }
650                 }
651         }
652         
653         
654         
655         protected void handleComplexTypeAttributes(SchemaObject complexType) {          
656                 handleAttributes(complexType,complexType.getComplexType().getAttributeOrAttributeGroup());
657         }
658         
659         protected void handleElementComplexTypeAttributes(SchemaObject complexType) {
660                 if (complexType != null) {
661                         handleComplexTypeAttributes(complexType);
662                         handleExtensionAttributes(complexType);
663                 }
664         }
665         
666         protected void handleElementSimpleTypeAttributes(SchemaObject simpleType) {
667                 if (simpleType != null) {
668                         handleAttributes(simpleType);
669                 }
670         }
671         
672         protected Set<Annotated> handleAttributeCompositions(SchemaObject obj, List<Annotated> attributeOrAttributeGroup) {
673                 
674                 Set<Annotated> handled = new HashSet<Annotated>();
675                 for (JAXBElement<?> e : configuration.getConversionRule()) {
676                         if (e.getValue() instanceof AttributeComposition) {
677                                 AttributeComposition composition = (AttributeComposition)e.getValue();
678                                 if (composition.getAttribute().size() < 2)
679                                         throw new RuntimeException("Attribute Composition is not valid");
680                                 BijectionMap<org.simantics.xml.sax.configuration.Attribute, Annotated> map = new BijectionMap<org.simantics.xml.sax.configuration.Attribute, Annotated>();
681                                 for (org.simantics.xml.sax.configuration.Attribute a : composition.getAttribute()) {
682                                         for (Annotated annotated : attributeOrAttributeGroup) {
683                                                 if (annotated instanceof Attribute) {
684                                                         Attribute attribute = (Attribute)annotated;
685                                                         QName type = getBaseType(attribute);
686                                                         if (a.getName().equals(attribute.getName()) && type != null && a.getType().equals(type.getLocalPart())) {
687                                                                 map.map(a, attribute);
688                                                         }
689                                                 }
690                                         }
691                                 }
692                                 if (composition.getAttribute().size() == map.size()) {
693                                         handled.addAll(map.getRightSet());
694                                         handleAttributeComposition(obj, composition, map);      
695                                 }
696                         }
697                 }
698                 return handled;
699         }
700         
701         protected QName getBaseType(Attribute attribute) {
702                 if (attribute.getType() != null)
703                         return attribute.getType();
704                 if (attribute.getRef() != null)
705                         return attribute.getRef();
706                 SimpleType simpleType = attribute.getSimpleType();
707                 if (simpleType != null) {
708                         Restriction restriction = simpleType.getRestriction();
709                         if (restriction != null)
710                                 if (restriction.getBase() != null)
711                                         return restriction.getBase();
712                 }
713                 return null;
714         }
715         
716         protected QName getPrimitiveType(Attribute attribute) {
717                 QName type = getBaseType(attribute);
718                 String b = getBindingFromPrimitiveType(type);
719                 while (b==null && type != null) {
720                         SchemaObject baseType = simpleTypeName.get(type.getLocalPart());
721                         if (baseType != null) {
722                                 Restriction restriction = baseType.getSimpleType().getRestriction();
723                                 if (restriction != null)
724                                         if (restriction.getBase() != null) {
725                                                 type = restriction.getBase();
726                                                 b = getBindingFromPrimitiveType(type);
727                                         }
728                         }
729                 }
730                 return type;
731         }
732         
733         protected Attribute getRefAttribute(QName ref) {
734                 for (OpenAttrs attrs : schema.getSimpleTypeOrComplexTypeOrGroup()) {
735                         if (attrs instanceof TopLevelAttribute) {
736                                 TopLevelAttribute attribute = (TopLevelAttribute)attrs;
737                                 if (attribute.getName().equals(ref.getLocalPart()))
738                                         return attribute;
739                         }
740                 }
741                 return null;
742         }
743         
744         //protected abstract void handleAttributeComposition(SchemaObject obj, AttributeComposition composition, BijectionMap<org.simantics.xml.sax.configuration.Attribute, Annotated> attributes);
745         protected void handleAttributeComposition(SchemaObject obj, AttributeComposition composition, BijectionMap<org.simantics.xml.sax.configuration.Attribute, Annotated> attributes) {
746                 component.handleAttributeComposition(obj, composition, attributes);
747         }
748         
749         
750         
751         
752         protected void handleComplexType(SchemaObject complexType) {
753 //              handleComplexTypeAttributes(complexType);
754 //              handleComplexTypeExtension(complexType);
755 //              handleExtensionAttributes(complexType);
756                 component.handleComplexType(complexType);
757         }
758         
759         protected void handleElement(SchemaObject topLevelElement) {
760 //              LocalComplexType complexType = topLevelElement.getElement().getComplexType();
761 //              
762 //              if (complexType != null) {
763 //                      SchemaObject complextTypeObj = complexTypes.get(complexType);
764 //                      handleElementComplexTypeAttributes(complextTypeObj);
765 //                      handleComplexTypeExtension(complextTypeObj);
766 //              }       
767                 component.handleElement(topLevelElement);
768         }
769         
770         protected enum RefType{Element,Reference,Type};
771         
772         protected void handleIndicator(SchemaObject parent, SchemaElement indicator, SchemaElement element, String refName, RefType refType, 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 getElementName(Element localElement) {
956                 if (localElement.getName() != null) {
957                         String refName = localElement.getName();
958                         QName refType = localElement.getType();
959                         if (refType != null)
960                                 return refName;
961                 } else if (localElement.getRef() != null) {
962                         QName refType = localElement.getRef();
963                         if (refType != null)
964                                 return refType.getLocalPart();
965                 }
966                 return null;
967         }
968         
969         protected String getChoiceName(List<SchemaElement> elements) {
970                 if (elements.size() == 1) {
971                         return null;
972                 }
973                 else if (elements.size() > 0 && elements.size() <= 3) {
974                         List<String> names = new ArrayList<String>();
975                         for (SchemaElement e : elements) {
976                                 String name = getElementName(e.getElement());
977                                 if (name != null)
978                                         names.add(name);
979                         }
980                         String name = "";
981                         for (int i = 0; i < names.size(); i++) {
982                                 if (i == 0)
983                                         name = names.get(i);
984                                 else
985                                         name += "Or"+names.get(i);
986                         }
987                         return name;
988                 }
989                 else {
990                         return "SubElement";
991                 }
992         }
993                 
994         protected void handle(SchemaObject parent, Attribute attribute) {
995                 component.handle(parent, attribute);
996         }
997         protected void handle(SchemaObject parent, AttributeGroup attribute) {
998                 component.handle(parent, attribute);
999         }
1000         protected void handle(SchemaObject parent, NamedGroup attribute){
1001                 component.handle(parent, attribute);
1002         };
1003         
1004         protected void handleSimpleType(SchemaObject parent, SchemaObject simpleType) {
1005                 component.handleSimpleType(parent, simpleType);
1006         }
1007         
1008         
1009         
1010         protected void handleComplexTypeExtension(SchemaObject complexTypeObj) {
1011                 ComplexType complexType = complexTypeObj.getComplexType();
1012                 if (complexType != null) {
1013                         if (complexType.getChoice() != null)
1014                                 handle(complexTypeObj, complexType.getChoice(), SchemaElement.ElementType.CHOICE);
1015                         if (complexType.getSequence() != null)
1016                                 handle(complexTypeObj, complexType.getSequence(), SchemaElement.ElementType.SEQUENCE);
1017                         if (complexType.getAll() != null)
1018                                 handle(complexTypeObj, complexType.getAll(), SchemaElement.ElementType.ALL);
1019                         if (complexType.getGroup() != null)
1020                                 throw new RuntimeException("Groups not supported");
1021                         ComplexContent complexContent = complexType.getComplexContent();
1022                         if (complexContent != null) {
1023                                 ExtensionType extensionType = complexContent.getExtension();
1024                                 if (extensionType != null) {
1025                                         if (extensionType.getChoice() != null) {
1026                                                 handle(complexTypeObj, extensionType.getChoice(), SchemaElement.ElementType.CHOICE);
1027                                         }
1028                                         if (extensionType.getSequence()!= null) {
1029                                                 handle(complexTypeObj, extensionType.getSequence(), SchemaElement.ElementType.SEQUENCE);
1030                                         }
1031                                         if (extensionType.getAll()!= null) {
1032                                                 handle(complexTypeObj, extensionType.getAll(), SchemaElement.ElementType.ALL);
1033                                         }
1034                                         if (extensionType.getGroup() != null) {
1035                                                 throw new RuntimeException("Groups not supported");
1036                                                 //handle(complexTypeObj, extensionType.getGroup(), SchemaElement.ElementType.GROUP_REF);
1037                                         }
1038                                 }
1039                         }
1040 //                      SimpleContent simpleContent = complexType.getSimpleContent();
1041 //                      if (simpleContent != null) {
1042 //                              ExtensionType extensionType = simpleContent.getExtension();
1043 //                      }
1044                 }
1045         }
1046         
1047         
1048         public boolean isElementRef(String ref) {
1049                 return elementName.containsKey(ref);
1050         }
1051         
1052         public boolean isComplexTypeRef(String ref) {
1053                 return complexTypeName.containsKey(ref);
1054         }
1055         
1056         public boolean isSimpleTypeRef(String ref) {
1057                 return simpleTypeName.containsKey(ref);
1058         }
1059         
1060         public IDProvider getIDProvider(Element element) {
1061                 List<IDProvider> idProviders = new ArrayList<IDProvider>(2);
1062                 for (JAXBElement<?> e : configuration.getConversionRule()) {
1063                         if (e.getValue() instanceof IDProvider) {
1064                                 IDProvider ref = (IDProvider)e.getValue();
1065                                 org.simantics.xml.sax.configuration.Element element2 = ref.getElement();
1066                                 if (element2 != null) {
1067                                         if (element.getName().equals(element2.getName()))
1068                                                 idProviders.add(ref);
1069                                 }
1070                                 
1071                         }
1072                 }
1073                 if (idProviders.size() == 0)
1074                         return null;
1075                 if (idProviders.size() > 1)
1076                         throw new RuntimeException("Element " + element.getName() + " contains " + idProviders.size() + " id provider rules, only one is allowed.");
1077                 return idProviders.get(0);
1078         }
1079         
1080         public IDProvider getIDProvider(ComplexType complexType) {
1081                 List<IDProvider> idProviders = new ArrayList<IDProvider>(2);
1082                 for (JAXBElement<?> e : configuration.getConversionRule()) {
1083                         if (e.getValue() instanceof IDProvider) {
1084                                 IDProvider ref = (IDProvider)e.getValue();
1085                                 org.simantics.xml.sax.configuration.ComplexType complexType2 = ref.getComplexType();
1086                                 if (complexType2 != null) {
1087                                         if (complexType.getName().equals(complexType2.getName()))
1088                                                 idProviders.add(ref);
1089                                 }
1090
1091                         }
1092                 }
1093                 if (idProviders.size() == 0)
1094                         return null;
1095                 if (idProviders.size() > 1)
1096                         throw new RuntimeException("Element " + complexType.getName() + " contains " + idProviders.size() + " id provider rules, only one is allowed.");
1097                 return idProviders.get(0);
1098         }
1099         
1100         public List<IDReference> getIDReferences(Element element) {
1101                 List<IDReference> idReferences = new ArrayList<IDReference>(2);
1102                 for (JAXBElement<?> e : configuration.getConversionRule()) {
1103                         if (e.getValue() instanceof IDReference) {
1104                                 IDReference ref = (IDReference)e.getValue();
1105                                 org.simantics.xml.sax.configuration.Element element2 = ref.getElement();
1106                                 if (element2 != null) {
1107                                         if (element.getName().equals(element2.getName()))
1108                                                 idReferences.add(ref);
1109                                 }
1110                         }
1111                 }
1112                 return idReferences;
1113         }
1114         
1115         public List<IDReference> getIDReferences(ComplexType complexType) {
1116                 List<IDReference> idReferences = new ArrayList<IDReference>(2);
1117                 for (JAXBElement<?> e : configuration.getConversionRule()) {
1118                         if (e.getValue() instanceof IDReference) {
1119                                 IDReference ref = (IDReference)e.getValue();
1120                                 org.simantics.xml.sax.configuration.ComplexType complexType2 = ref.getComplexType();
1121                                 if (complexType2 != null) {
1122                                         if (complexType.getName().equals(complexType2.getName()))
1123                                                 idReferences.add(ref);
1124                                 }
1125                         }
1126                 }
1127                 return idReferences;
1128         }
1129         
1130         public UnrecognizedChildElement getUnknown(ComplexType complexType) {
1131                 for (JAXBElement<?> e : configuration.getConversionRule()) {
1132                         if (e.getValue() instanceof UnrecognizedChildElement) {
1133                                 UnrecognizedChildElement rule = (UnrecognizedChildElement)e.getValue();
1134                                 org.simantics.xml.sax.configuration.ComplexType complexType2 = rule.getComplexType();
1135                                 if (complexType2 != null) {
1136                                         if (complexType.getName().equals(complexType2.getName()))
1137                                                 return rule;
1138                                 }
1139                         }
1140                 }
1141                 return null;
1142         }
1143         
1144         public UnrecognizedChildElement getUnknown(Element element) {
1145                 for (JAXBElement<?> e : configuration.getConversionRule()) {
1146                         if (e.getValue() instanceof UnrecognizedChildElement) {
1147                                 UnrecognizedChildElement rule = (UnrecognizedChildElement)e.getValue();
1148                                 org.simantics.xml.sax.configuration.Element element2 = rule.getElement();
1149                                 if (element2 != null) {
1150                                         if (element.getName().equals(element2.getName()))
1151                                                 return rule;
1152                                 }
1153                         }
1154                 }
1155                 return null;
1156         }
1157         
1158         public Rename getRename(Attribute element) {
1159                 for (JAXBElement<?> e : configuration.getConversionRule()) {
1160                         if (e.getValue() instanceof Rename) {
1161                                 Rename rule = (Rename)e.getValue();
1162                                 Object ref = rule.getElementOrComplexTypeOrAttribute().get(0);
1163                                 if (!(ref instanceof org.simantics.xml.sax.configuration.Attribute))
1164                                         continue;
1165                                 org.simantics.xml.sax.configuration.Attribute element2 = (org.simantics.xml.sax.configuration.Attribute)ref;
1166                                 if (element2.getName().equals(element.getName())) {
1167                                         return rule;
1168                                 }
1169                         }
1170                 }
1171                 return null;
1172         }
1173         
1174         public Rename getRename(ComplexType element) {
1175                 for (JAXBElement<?> e : configuration.getConversionRule()) {
1176                         if (e.getValue() instanceof Rename) {
1177                                 Rename rule = (Rename)e.getValue();
1178                                 Object ref = rule.getElementOrComplexTypeOrAttribute().get(0);
1179                                 if (!(ref instanceof org.simantics.xml.sax.configuration.ComplexType))
1180                                         continue;
1181                                 org.simantics.xml.sax.configuration.ComplexType element2 = (org.simantics.xml.sax.configuration.ComplexType)ref;
1182                                 if (element2.getName().equals(element.getName())) {
1183                                         return rule;
1184                                 }
1185                         }
1186                 }
1187                 return null;
1188         }
1189         
1190         public Rename getRename(Element element) {
1191                 for (JAXBElement<?> e : configuration.getConversionRule()) {
1192                         if (e.getValue() instanceof Rename) {
1193                                 Rename rule = (Rename)e.getValue();
1194                                 Object ref = rule.getElementOrComplexTypeOrAttribute().get(0);
1195                                 if (!(ref instanceof org.simantics.xml.sax.configuration.Element))
1196                                         continue;
1197                                 org.simantics.xml.sax.configuration.Element element2 = (org.simantics.xml.sax.configuration.Element)ref;
1198                                 if (element2.getName().equals(element.getName())) {
1199                                         return rule;
1200                                 }
1201                         }
1202                 }
1203                 return null;
1204         }
1205          
1206         
1207         public boolean useOriginalList(SchemaObject parent, SchemaElement indicator, SchemaElement element,  boolean reference, String ref, QName refType) {
1208                 if (parent.getName() == null)
1209                         parent = parent.getParent();
1210                 if (parent.getName().contains("PipingNetworkSegment"))
1211                         System.out.println();
1212                 for (JAXBElement<?> e : configuration.getConversionRule()) {
1213                         if (e.getValue() instanceof OrderedChild) {
1214                                 OrderedChild oc = (OrderedChild)e.getValue();
1215                                 org.simantics.xml.sax.configuration.Element element2 = oc.getElement();
1216                                 org.simantics.xml.sax.configuration.ComplexType complexType = oc.getComplexType();
1217                                 org.simantics.xml.sax.configuration.Element child = oc.getChild();
1218                                 if (!oc.getType().equals("original"))
1219                                         continue;
1220                                 boolean match = false;
1221                                 if (element2 != null) {
1222                                         if (parent.getType() == ObjectType.ELEMENT && parent.getName().equals(element2.getName())) {
1223                                                 match = true;
1224                                         }
1225                                 } else if (complexType != null) {
1226                                         if (parent.getType() == ObjectType.COMPLEX_TYPE && parent.getName() != null && parent.getName().equals(complexType.getName())) {
1227                                                 match = true;
1228                                         }
1229                                         
1230                                 }
1231                                 if (match) {
1232                                         if (child != null) {
1233                                                 if (matchChild(child, ref, refType)) {
1234                                                         if (oc.getValue().equals("disable"))
1235                                                                 return false;
1236                                                         else return true;
1237                                                 }
1238                                         } else { 
1239                                                 if (oc.getValue().equals("disable"))
1240                                                         return false;
1241                                                 return true;
1242                                         }
1243                                         
1244                                 }
1245                         }
1246                 }
1247                 return indicator.order();
1248         }
1249         
1250         public boolean useElementList(SchemaObject parent, SchemaElement indicator, SchemaElement element,  boolean reference, String refName, QName refType) {
1251                 if (parent.getName() == null)
1252                         parent = parent.getParent();
1253                 if (parent.getName() == "PipingNetworkSegment")
1254                         System.out.println();
1255                 for (JAXBElement<?> e : configuration.getConversionRule()) {
1256                         if (e.getValue() instanceof OrderedChild) {
1257                                 OrderedChild oc = (OrderedChild)e.getValue();
1258                                 org.simantics.xml.sax.configuration.Element element2 = oc.getElement();
1259                                 org.simantics.xml.sax.configuration.ComplexType complexType = oc.getComplexType();
1260                                 org.simantics.xml.sax.configuration.Element child = oc.getChild();
1261                                 if (!oc.getType().equals("child"))
1262                                         continue;
1263                                 boolean match = false;
1264                                 if (element2 != null) {
1265                                         if (parent.getType() == ObjectType.ELEMENT && parent.getName().equals(element2.getName())) {
1266                                                 match = true;
1267                                         }
1268                                 } else if (complexType != null) {
1269                                         if (parent.getType() == ObjectType.COMPLEX_TYPE && parent.getName() != null && parent.getName().equals(complexType.getName())) {
1270                                                 match = true;
1271                                         }
1272                                         
1273                                 }
1274                                 if (match) {
1275                                         if (child != null) {
1276                                                 if (matchChild(child, refName, refType)) {
1277                                                         if (oc.getValue().equals("disable"))
1278                                                                 return false;
1279                                                         else return true;
1280                                                 }
1281                                         } else {
1282                                                 if (oc.getValue().equals("disable"))
1283                                                         return false;
1284                                                 return true;
1285                                         }
1286                                         
1287                                 }
1288                         }
1289                 }
1290                 return element.many() && element.order();
1291         }
1292         
1293         private boolean matchChild(org.simantics.xml.sax.configuration.Element child, String refName, QName refType) {
1294                 if (refType != null && refType.getLocalPart().equals(child.getName()))
1295                         return true;
1296                 if (refName != null && refName.equals(child.getName()))
1297                         return true;
1298                 return false;
1299         }
1300         
1301         public static class TypeEntry {
1302                 String l0Type;
1303                 String binding;
1304                 String javaType;
1305                 String defaultValue;
1306                 boolean id;
1307                 String getterPrefix;
1308                 String getterPostfix;
1309                 String stringPrefix;
1310                 String stringPostfix;
1311                 public TypeEntry(String l0Type, String binding, String javaType, String defaultValue, String getterPrefix, String getterPostfix, String stringPrefix, String stringPostfix) {
1312                         super();
1313                         this.l0Type = l0Type;
1314                         this.binding = binding;
1315                         this.javaType = javaType;
1316                         this.defaultValue = defaultValue;
1317                         this.id = false;
1318                         this.getterPrefix = getterPrefix;
1319                         this.getterPostfix = getterPostfix;
1320                         this.stringPrefix = stringPrefix;
1321                         this.stringPostfix = stringPostfix;
1322                 }
1323                 
1324                 public TypeEntry(String l0Type, String binding, String javaType, String defaultValue, String getterPrefix, String getterPostfix, String stringPrefix, String stringPostfix, boolean id) {
1325                         super();
1326                         this.l0Type = l0Type;
1327                         this.binding = binding;
1328                         this.javaType = javaType;
1329                         this.defaultValue = defaultValue;
1330                         this.id = id;
1331                         this.getterPrefix = getterPrefix;
1332                         this.getterPostfix = getterPostfix;
1333                         this.stringPrefix = stringPrefix;
1334                         this.stringPostfix = stringPostfix;
1335                 }
1336                 
1337                 public String getValueGetterMethod(String name) {
1338                         return getterPrefix + name + ".getValue()"+getterPostfix;
1339                 }
1340                 public String getValueGetter(String name) {
1341                         return getterPrefix + name+getterPostfix;
1342                 }
1343                 public String getValueGetter()
1344                 {
1345                         return getValueGetter("value");
1346                 }
1347                 
1348                 public String getToString(String name) {
1349                         return stringPrefix +"("+javaType+")"+name+stringPostfix;
1350                 }
1351                 
1352                 public String getElementToString(String name) {
1353                         return stringPrefix + name+stringPostfix;
1354                 }
1355                 
1356         }
1357         
1358         public enum InheritanceType{ComplexType,AtomicType,None};
1359         
1360         public static class Inheritance {
1361                 public String baseClass;
1362                 public String additionalClass;
1363                 public InheritanceType type;
1364                 public TypeEntry atomicType;
1365                 
1366                 public Inheritance(String baseClass) {
1367                         this.baseClass = baseClass;
1368                         this.type = InheritanceType.None;
1369                 }
1370         }
1371         
1372         public String getComplexTypePrefix() {
1373                 return component.getComplexTypePrefix();
1374         }
1375         public String getAttributeGroupPrefix() {
1376                 return component.getAttributeGroupPrefix();
1377         }
1378         public String getName(SchemaObject obj) {
1379                 return component.getName(obj);
1380         }
1381         public String getBaseClass(ObjectType type) {
1382                 return component.getBaseClass(type);
1383         }
1384         
1385         
1386         
1387         public Inheritance getInheritance(SchemaObject topLevelObj) {
1388                 Inheritance inheritance = null;
1389                 if (topLevelObj.getType() == ObjectType.ELEMENT) {
1390                         Element topLevelElement = topLevelObj.getElement();
1391                         inheritance = new Inheritance(getBaseClass(ObjectType.ELEMENT));
1392                         if (topLevelElement.getType() != null) {
1393                                 QName type = topLevelElement.getType();
1394                                 if (!type.getNamespaceURI().equals(SCHEMA_NS)) {
1395                                         SchemaObject obj = complexTypeName.get(type.getLocalPart());
1396                                         if (obj != null) {
1397                                                 inheritance.baseClass = getName(obj);
1398                                                 inheritance.type = InheritanceType.ComplexType;
1399                                         }
1400                                         else {
1401                                                 obj = simpleTypeName.get(type.getLocalPart());
1402                                                 if (obj != null)
1403                                                         getAtomicTypeInheritance(type, inheritance);
1404                                         }
1405                                 } else {
1406                                         TypeEntry entry = getTypeEntry(type);
1407                                         if (entry != null) {
1408                                                 inheritance.type = InheritanceType.AtomicType;
1409                                                 inheritance.atomicType = entry;
1410                                         }
1411                                 }
1412                         }
1413                         if (inheritance.type == InheritanceType.None) {
1414                                 QName type = getElementBase(topLevelElement);
1415                                 if (type != null) {
1416                                         if (!type.getNamespaceURI().equals(SCHEMA_NS)) {
1417                                                 SchemaObject obj = getWithName(type);
1418                                                 inheritance.baseClass = getName(obj);
1419                                                 inheritance.type = InheritanceType.ComplexType;
1420                                         } else {
1421                                                 TypeEntry entry = getTypeEntry(type);
1422                                                 if (entry != null) {
1423                                                         inheritance.type = InheritanceType.AtomicType;
1424                                                         inheritance.atomicType = entry;
1425                                                 }
1426                                         }
1427                                 }
1428                         }
1429                         if (inheritance.type == InheritanceType.None) {
1430                                 QName type = topLevelElement.getSubstitutionGroup();
1431                                 if (type != null) {
1432                                         if (!type.getNamespaceURI().equals(SCHEMA_NS)) {
1433                                                 SchemaObject obj = getWithName(type);
1434                                                 inheritance.baseClass = getName(obj);
1435                                                 inheritance.type = InheritanceType.ComplexType;
1436                                         } else {
1437                                                 TypeEntry entry = getTypeEntry(type);
1438                                                 if (entry != null) {
1439                                                         inheritance.type = InheritanceType.AtomicType;
1440                                                         inheritance.atomicType = entry;
1441                                                 }
1442                                         }
1443                                 }
1444                         }
1445                 } else if (topLevelObj.getType() == ObjectType.COMPLEX_TYPE) {
1446                         ComplexType complexType = topLevelObj.getComplexType();
1447                         QName type = getComplexTypeBase(complexType);
1448                         inheritance = new Inheritance(getBaseClass(ObjectType.COMPLEX_TYPE));
1449                         if (type != null && !type.getNamespaceURI().equals("http://www.w3.org/2001/XMLSchema")) {
1450                                 SchemaObject obj = complexTypeName.get(type.getLocalPart());
1451                                 if (obj != null) {
1452                                         inheritance.baseClass = getName(obj);
1453                                         inheritance.type = InheritanceType.ComplexType;
1454                                 }
1455                         }
1456                         SimpleContent simpleContent = complexType.getSimpleContent();
1457                         if (simpleContent != null) {
1458                                 ExtensionType extensionType = simpleContent.getExtension();
1459                                 if (extensionType != null) {
1460                                         type = extensionType.getBase();
1461                                         SchemaObject simpleType = getSimpleType(type);
1462                                         if (simpleType != null)
1463                                                 inheritance.additionalClass = getName(simpleType);
1464                                         getAtomicTypeInheritance(type, inheritance);
1465                                 }
1466                         }
1467                 }
1468                 
1469                 return inheritance;
1470         }       
1471         /**
1472          * Goes through chain of SimpleTypes until locates Atomic Type (type defined in XML schema). 
1473          * @param type
1474          * @param topLevelObj
1475          * @param inheritance
1476          */
1477         public void getAtomicTypeInheritance(QName type, Inheritance inheritance) {
1478                 if (!type.getNamespaceURI().equals(SCHEMA_NS)) {
1479                         SchemaObject obj = getSimpleType(type);
1480                         if (obj == null)
1481                                 throw new RuntimeException("Cannot locate SimpleType " + type.getLocalPart());
1482                         SimpleType simpleType = obj.getSimpleType();
1483                         type = getSimpleTypeBase(simpleType);
1484                         getAtomicTypeInheritance(type, inheritance);
1485                 } else {
1486                         TypeEntry entry = getTypeEntry(type);
1487                         if (entry != null) {
1488                                 inheritance.type = InheritanceType.AtomicType;
1489                                 inheritance.atomicType = entry;
1490                         }
1491                 }
1492         }
1493         
1494         public String getDefaultValue(QName atype) {
1495                 Map<String,TypeEntry> types = typeMap.get(atype.getNamespaceURI());
1496                 if (types == null)
1497                         return null;
1498                 TypeEntry entry =  types.get(atype.getLocalPart());
1499                 if (entry == null)
1500                         return null;
1501                 return entry.defaultValue;
1502         }
1503
1504 }