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