]> gerrit.simantics Code Review - simantics/interop.git/blob - org.simantics.xml.sax/src/org/simantics/xml/sax/SchemaConversionBase.java
f35a8845acc74e7a0e081ffdf76498c67b7cf5b9
[simantics/interop.git] / org.simantics.xml.sax / src / org / simantics / xml / 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.UnrecognizedChildElement;\r
24 import org.w3._2001.xmlschema.All;\r
25 import org.w3._2001.xmlschema.Annotated;\r
26 import org.w3._2001.xmlschema.Any;\r
27 import org.w3._2001.xmlschema.Attribute;\r
28 import org.w3._2001.xmlschema.AttributeGroup;\r
29 import org.w3._2001.xmlschema.ComplexContent;\r
30 import org.w3._2001.xmlschema.ComplexType;\r
31 import org.w3._2001.xmlschema.Element;\r
32 import org.w3._2001.xmlschema.ExplicitGroup;\r
33 import org.w3._2001.xmlschema.ExtensionType;\r
34 import org.w3._2001.xmlschema.LocalComplexType;\r
35 import org.w3._2001.xmlschema.LocalElement;\r
36 import org.w3._2001.xmlschema.NamedAttributeGroup;\r
37 import org.w3._2001.xmlschema.OpenAttrs;\r
38 import org.w3._2001.xmlschema.Restriction;\r
39 import org.w3._2001.xmlschema.Schema;\r
40 import org.w3._2001.xmlschema.SimpleType;\r
41 import org.w3._2001.xmlschema.TopLevelAttribute;\r
42 import org.w3._2001.xmlschema.TopLevelComplexType;\r
43 import org.w3._2001.xmlschema.TopLevelElement;\r
44 import org.w3._2001.xmlschema.TopLevelSimpleType;\r
45 \r
46 public abstract class SchemaConversionBase {\r
47         \r
48         protected Schema schema;\r
49         protected Configuration configuration;\r
50         \r
51         protected static final String SCHEMA_NS = "http://www.w3.org/2001/XMLSchema";\r
52         protected static final String CONVERSION_NS = "http://www.simantics.org/Layer0";\r
53         \r
54         protected Map<String,Map<String,TypeEntry>> typeMap;\r
55         \r
56         public SchemaConversionBase(Configuration configuration) {\r
57                 this.configuration = configuration;\r
58                 typeMap = new HashMap<String, Map<String,TypeEntry>>();\r
59                 \r
60                 Map<String,TypeEntry> schemaTypes = new HashMap<String, SchemaConversionBase.TypeEntry>();\r
61                 typeMap.put(SCHEMA_NS, schemaTypes);\r
62                 Map<String,TypeEntry> l0Types = new HashMap<String, SchemaConversionBase.TypeEntry>();\r
63                 typeMap.put(CONVERSION_NS, l0Types);\r
64                 \r
65                 schemaTypes.put("string",               new TypeEntry("L0.String",                      "STRING", "String", ""));\r
66                 schemaTypes.put("NMTOKEN",              new TypeEntry("L0.String",                      "STRING", "String", ""));\r
67                 schemaTypes.put("token",                new TypeEntry("L0.String",                      "STRING", "String", ""));\r
68                 schemaTypes.put("ID",                   new TypeEntry("L0.String",                      "STRING", "String", "",true));\r
69                 schemaTypes.put("IDREF",                new TypeEntry("L0.String",                      "STRING", "String", ""));\r
70                 schemaTypes.put("date",                 new TypeEntry("L0.String",                      "STRING", "String", ""));\r
71                 schemaTypes.put("time",                 new TypeEntry("L0.String",                      "STRING", "String", ""));\r
72                 schemaTypes.put("anyURI",               new TypeEntry("L0.URI",                         "STRING", "String", ""));\r
73                 schemaTypes.put("double",               new TypeEntry("L0.Double",                      "DOUBLE", "double", "Double.NaN"));\r
74                 schemaTypes.put("float",                new TypeEntry("L0.Float",                       "FLOAT",  "float",  "Float.NaN"));\r
75                 schemaTypes.put("decimal",              new TypeEntry("L0.Double",                      "DOUBLE", "double", "Double.NaN"));\r
76                 schemaTypes.put("boolean",              new TypeEntry("L0.Boolean",                     "BOOLEAN", "boolean", "false"));\r
77                 schemaTypes.put("integer",              new TypeEntry("L0.Integer",             "INTEGER", "int", "0"));\r
78                 schemaTypes.put("positiveInteger", new TypeEntry("L0.Integer",          "INTEGER", "int", "0"));\r
79                 schemaTypes.put("nonPositiveInteger", new TypeEntry("L0.Integer",       "INTEGER", "int", "0"));\r
80                 schemaTypes.put("nonNegativeInteger", new TypeEntry("L0.Integer",       "INTEGER", "int", "0"));\r
81                 schemaTypes.put("negativeInteger", new TypeEntry("L0.Integer",          "INTEGER", "int", "0"));\r
82                 schemaTypes.put("unsignedInt",  new TypeEntry("L0.Integer",             "INTEGER", "int", "0"));\r
83                 schemaTypes.put("int",                  new TypeEntry("L0.Integer",                     "INTEGER", "int", "0"));\r
84                 schemaTypes.put("short",                new TypeEntry("L0.Integer",                     "INTEGER", "int", "0"));\r
85                 schemaTypes.put("unsignedShort",new TypeEntry("L0.Integer",                     "INTEGER", "int", "0"));\r
86                 schemaTypes.put("byte",                 new TypeEntry("L0.Byte",                        "BYTE", "byte", "0"));\r
87                 schemaTypes.put("unsignedByte", new TypeEntry("L0.Byte",                        "BYTE", "byte", "0"));\r
88                 schemaTypes.put("long",                 new TypeEntry("L0.Long",                        "LONG", "long", "0"));\r
89                 schemaTypes.put("unsignedLong", new TypeEntry("L0.Long",                        "LONG", "long", "0"));\r
90                 \r
91                 \r
92                 \r
93                 l0Types.put("doubleArray",              new TypeEntry("L0.DoubleArray",  "DOUBLE_ARRAY", "double[]", null));\r
94                 l0Types.put("stringArray",              new TypeEntry("L0.StringArray",  "STRING_ARRAY", "string[]", null));\r
95         }\r
96         \r
97         \r
98         protected TypeEntry getTypeEntry(QName type) {\r
99                 Map<String,TypeEntry> types = typeMap.get(type.getNamespaceURI());\r
100                 if (types == null)\r
101                         return null;\r
102                 TypeEntry entry = types.get(type.getLocalPart());\r
103                 return entry;\r
104                 \r
105         }\r
106         \r
107         protected String getL0TypeFromPrimitiveType(QName primitiveType) {\r
108                 TypeEntry entry = getTypeEntry(primitiveType);\r
109                 if (entry == null)\r
110                         return null;\r
111                 return entry.l0Type;\r
112         }\r
113         \r
114         protected String getL0Type(QName primitiveType) {\r
115                 String type = getL0TypeFromPrimitiveType(primitiveType);\r
116                 if (type != null)\r
117                         return type;\r
118                 SchemaObject simpleTypeObj = simpleTypeName.get(primitiveType.getLocalPart());\r
119                 if (simpleTypeObj == null)\r
120                         return null;\r
121                 SimpleType simpleType = simpleTypeObj.getSimpleType();\r
122                 while (simpleType != null) {\r
123                         QName base = simpleType.getRestriction().getBase();\r
124                         if (base != null)\r
125                                 return getL0Type(base);\r
126                         simpleType = simpleType.getRestriction().getSimpleType();\r
127                 }\r
128                 return null;\r
129         }\r
130         \r
131         protected String getBindingFromPrimitiveType(QName primitiveType) {\r
132                 TypeEntry entry = getTypeEntry(primitiveType);\r
133                 if (entry == null)\r
134                         return null;\r
135                 return entry.binding;\r
136         }\r
137         \r
138         protected String getJavaTypeFromPrimitiveType(QName primitiveType) {\r
139                 TypeEntry entry = getTypeEntry(primitiveType);\r
140                 if (entry == null)\r
141                         return null;\r
142                 return entry.javaType;\r
143         }\r
144         \r
145         \r
146         protected void handle(Schema schema) {  \r
147                 this.schema = schema;\r
148                 preload();\r
149                 \r
150                 for (OpenAttrs attrs : schema.getSimpleTypeOrComplexTypeOrGroup()) {\r
151                         if (attrs instanceof TopLevelAttribute) {\r
152                                 handle((TopLevelAttribute)attrs);\r
153                                 \r
154                         } else if (attrs instanceof TopLevelComplexType) {\r
155                                 handleComplexType(complexTypes.get(attrs));\r
156                         } else if (attrs instanceof TopLevelElement) {\r
157                                 handleElement(elements.get(attrs));\r
158                         } else if (attrs instanceof TopLevelSimpleType) {\r
159                                 handleSimpleType(simpleTypes.get(attrs));\r
160                         } else if (attrs instanceof NamedAttributeGroup) {\r
161                                 handle((NamedAttributeGroup)attrs);\r
162                         } else {\r
163                                 System.out.println(attrs.getClass().getName());\r
164                         }\r
165                 }\r
166         }\r
167         \r
168         protected Map<String,SchemaObject> elementName = new HashMap<String, SchemaObject>();\r
169         protected Map<String,SchemaObject> complexTypeName = new HashMap<String, SchemaObject>();\r
170         protected Map<String,SchemaObject> simpleTypeName = new HashMap<String, SchemaObject>();\r
171         protected Map<Element,SchemaObject> elements = new HashMap<Element, SchemaObject>();\r
172         protected Map<ComplexType,SchemaObject> complexTypes = new HashMap<ComplexType, SchemaObject>();\r
173         protected Map<SimpleType,SchemaObject> simpleTypes = new HashMap<SimpleType, SchemaObject>();\r
174         \r
175         \r
176         protected SchemaObject getWithName(SchemaObject referrer, String name) {\r
177                 SchemaObject obj = elementName.get(name);\r
178                 if (obj == null)\r
179                         obj = complexTypeName.get(name);\r
180                 if (obj == null)\r
181                         obj = simpleTypeName.get(name);\r
182                 if (obj == null) {\r
183                         throw new RuntimeException("Cannot locate referred type " + name + " when handling " + referrer.getName());\r
184                 }\r
185                 return obj;\r
186         }\r
187         \r
188         protected SchemaObject getWithObj(SchemaObject referrer, OpenAttrs attrs) {\r
189                 SchemaObject obj = null;\r
190                 if (attrs instanceof Element)\r
191                         obj = elements.get(attrs);\r
192                 else if (attrs instanceof ComplexType)\r
193                         obj = complexTypes.get(attrs);\r
194                 else if (attrs instanceof SimpleType) \r
195                         obj = simpleTypes.get(attrs);\r
196                 if (obj == null){\r
197                         throw new RuntimeException("Cannot locate referred object " + attrs + " when handling " + referrer.getName());\r
198                 }\r
199                 return obj;\r
200         }\r
201         \r
202         private void preload() {\r
203                 Deque<SchemaObject> stack = new ArrayDeque<SchemaObject>();\r
204                 //stack.addAll(schema.getSimpleTypeOrComplexTypeOrGroup());\r
205                 for (OpenAttrs attrs : schema.getSimpleTypeOrComplexTypeOrGroup()) {\r
206                         if (attrs instanceof Element) {\r
207                                 Element element = (Element)attrs;\r
208                                 SchemaObject obj = new SchemaObject(element);\r
209                                 stack.push(obj);\r
210                         } else if (attrs instanceof ComplexType) {\r
211                                 ComplexType complexType = (ComplexType)attrs;\r
212                                 SchemaObject obj = new SchemaObject(complexType);\r
213                                 stack.push(obj);\r
214                         } else if (attrs instanceof SimpleType) {\r
215                                 SimpleType simpleType = (SimpleType)attrs;\r
216                                 SchemaObject obj = new SchemaObject(simpleType);\r
217                                 stack.push(obj);\r
218                         }\r
219                 }\r
220                 \r
221                 while (!stack.isEmpty()) {\r
222                         SchemaObject object = stack.pop();\r
223                         if (object.getType() == ObjectType.COMPLEX_TYPE) {\r
224                                 ComplexType ct = object.getComplexType();\r
225                                 if (ct.getName() != null && ct.getName().length() > 0 && ct instanceof TopLevelComplexType)\r
226                                         complexTypeName.put(ct.getName(), object);\r
227                                 complexTypes.put(ct, object);\r
228                                 if (ct.getChoice() != null) {\r
229                                         preload(object,ct.getChoice(), stack);\r
230                                 }\r
231                                 if (ct.getSequence() != null) {\r
232                                         preload(object,ct.getSequence(), stack);\r
233                                 }\r
234                                 if (ct.getAll() != null) {\r
235                                         preload(object,ct.getAll(), stack);\r
236                                 }\r
237                                 if (ct.getGroup() != null)\r
238                                         throw new RuntimeException("Groups not supported");\r
239                                 if (ct.getComplexContent() != null) {\r
240                                         ComplexContent cc = ct.getComplexContent();\r
241                                         ExtensionType extensionType = cc.getExtension();\r
242                                         if (extensionType != null) {\r
243                                                 if (extensionType.getChoice() != null) {\r
244                                                         preload(object,extensionType.getChoice(), stack);\r
245                                                 }\r
246                                                 if (extensionType.getSequence()!= null) {\r
247                                                         preload(object,extensionType.getSequence(), stack);\r
248                                                 }\r
249                                                 if (extensionType.getAll()!= null) {\r
250                                                         preload(object,extensionType.getAll(), stack);\r
251                                                 }\r
252                                                 if (extensionType.getGroup() != null)\r
253                                                         throw new RuntimeException("Groups not supported");\r
254                                         }\r
255                                 }\r
256                         } else if (object.getType() == ObjectType.ELEMENT) {\r
257                                 Element e = object.getElement();\r
258                                 if (e instanceof TopLevelElement)\r
259                                         elementName.put(e.getName(), object);\r
260                                 elements.put(e, object);\r
261                                 if (e.getComplexType() != null)\r
262                                         stack.push(new SchemaObject(object,e.getComplexType()));\r
263                                 if (e.getSimpleType() != null)\r
264                                         stack.push(new SchemaObject(object,e.getSimpleType()));\r
265                         } else if (object.getType() == ObjectType.SIMPLE_TYPE) {\r
266                                 SimpleType e = object.getSimpleType();\r
267                                 if (e instanceof TopLevelSimpleType)\r
268                                         simpleTypeName.put(e.getName(), object);\r
269                                 simpleTypes.put(e, object);\r
270                         }\r
271                 }\r
272         }\r
273         \r
274         private void preload(SchemaObject parent,ExplicitGroup eg, Deque<SchemaObject> stack) {\r
275                 for (Object o : eg.getParticle()) {\r
276                         if (o instanceof JAXBElement<?>) {\r
277                                 JAXBElement<?> element = (JAXBElement<?>)o;\r
278                                 Object elemValue = element.getValue();\r
279                                 if (elemValue instanceof Element) {\r
280                                         stack.add(new SchemaObject(parent,(Element)elemValue));\r
281                                 } else if (elemValue instanceof All) {\r
282                                         preload(parent,(All)elemValue, stack);\r
283                                 } else if (elemValue instanceof ExplicitGroup) {\r
284                                         preload(parent,(ExplicitGroup)elemValue, stack);\r
285                                 } else {\r
286                                         throw new RuntimeException("Unknown ExplicitGroup element " + elemValue.getClass().getName());\r
287                                 }\r
288                         } else if (o instanceof Any){\r
289                                 \r
290                         } else {\r
291                                 throw new RuntimeException("Unknown ExplicitGroup reference " + o.getClass().getName());\r
292                         }\r
293                 }\r
294         }\r
295         \r
296         protected void handle(TopLevelAttribute topLevelAttribute) {\r
297                 handle(null, topLevelAttribute);\r
298         }\r
299         \r
300         protected void handleSimpleType(SchemaObject topLevelSimpleType) {\r
301                 handleSimpleType(null,topLevelSimpleType);\r
302         }\r
303         \r
304         protected void handle(NamedAttributeGroup namedAttributeGroup){\r
305                 handle(null, namedAttributeGroup);\r
306         }\r
307         \r
308         protected QName getComplexTypeBase(ComplexType complexType) {\r
309                 if (complexType == null)\r
310                         return null;\r
311                 ComplexContent complexContent = complexType.getComplexContent();\r
312                 if (complexContent != null) {\r
313                         ExtensionType extensionType = complexContent.getExtension();\r
314                         if (extensionType != null) {\r
315                                 QName type = extensionType.getBase();\r
316                                 return type;\r
317                         }\r
318                 }\r
319                 return null;\r
320         }\r
321         \r
322         protected QName getSimpleTypeBase(SimpleType simpleType) {\r
323                 if (simpleType == null)\r
324                         return null;\r
325                 return simpleType.getRestriction().getBase();\r
326         }\r
327         \r
328         protected QName getElementBase(Element element) {\r
329                 ComplexType complexType = element.getComplexType();\r
330                 SimpleType simpleType = element.getSimpleType();\r
331                 if (complexType != null)\r
332                         return getComplexTypeBase(complexType);\r
333                 if (simpleType != null) {\r
334                         return getSimpleTypeBase(simpleType);\r
335                 }\r
336                 return null;\r
337         }\r
338         \r
339 \r
340         \r
341         \r
342         \r
343         \r
344         \r
345         \r
346         private void handleAttributes(SchemaObject complexType, List<Annotated> attributeOrAttributeGroup) {\r
347                 //name = getComplexTypePrefix()+complexType.getName()\r
348                 \r
349                 Set<Annotated> handled = handleAttributeCompositions(complexType,attributeOrAttributeGroup);\r
350                 for (Annotated annotated : attributeOrAttributeGroup) {\r
351                         if (handled.contains(annotated))\r
352                                 continue;\r
353                         if (annotated instanceof Attribute) {\r
354                                 handle(complexType,(Attribute)annotated);\r
355                         } else if (annotated instanceof AttributeGroup){\r
356                                 handle(complexType,(AttributeGroup)annotated);\r
357                                 //comment("AttributeGroup " + ((AttributeGroup)annotated).getRef().getLocalPart());\r
358                         } else {\r
359                                 throw new RuntimeException();\r
360                         }\r
361                 }\r
362         }\r
363         \r
364         protected abstract void handleAttributes(SchemaObject simpleTypeObj);\r
365         \r
366         protected void handleExtensionAttributes(SchemaObject complexType) {\r
367                 ComplexContent complexContent = complexType.getComplexType().getComplexContent();\r
368                 if (complexContent != null) {\r
369                         ExtensionType extensionType = complexContent.getExtension();\r
370                         if (extensionType != null) {\r
371                                 handleAttributes(complexType, extensionType.getAttributeOrAttributeGroup());\r
372                         }\r
373                 }\r
374         }\r
375         \r
376         \r
377         \r
378         protected void handleComplexTypeAttributes(SchemaObject complexType) {          \r
379                 handleAttributes(complexType,complexType.getComplexType().getAttributeOrAttributeGroup());\r
380         }\r
381         \r
382         protected void handleElementComplexTypeAttributes(SchemaObject complexType) {\r
383                 if (complexType != null) {\r
384                         handleComplexTypeAttributes(complexType);\r
385                         handleExtensionAttributes(complexType);\r
386                 }\r
387         }\r
388         \r
389         protected void handleElementSimpleTypeAttributes(SchemaObject simpleType) {\r
390                 if (simpleType != null) {\r
391                         handleAttributes(simpleType);\r
392                 }\r
393         }\r
394         \r
395         protected Set<Annotated> handleAttributeCompositions(SchemaObject obj, List<Annotated> attributeOrAttributeGroup) {\r
396                 \r
397                 Set<Annotated> handled = new HashSet<Annotated>();\r
398                 for (JAXBElement<?> e : configuration.getConversionRule()) {\r
399                         if (e.getValue() instanceof AttributeComposition) {\r
400                                 AttributeComposition composition = (AttributeComposition)e.getValue();\r
401                                 if (composition.getAttribute().size() < 2)\r
402                                         throw new RuntimeException("Attribute Composition is not valid");\r
403                                 BijectionMap<org.simantics.xml.sax.configuration.Attribute, Annotated> map = new BijectionMap<org.simantics.xml.sax.configuration.Attribute, Annotated>();\r
404                                 for (org.simantics.xml.sax.configuration.Attribute a : composition.getAttribute()) {\r
405                                         for (Annotated annotated : attributeOrAttributeGroup) {\r
406                                                 if (annotated instanceof Attribute) {\r
407                                                         Attribute attribute = (Attribute)annotated;\r
408                                                         QName type = getBaseType(attribute);\r
409                                                         if (a.getName().equals(attribute.getName()) && type != null && a.getType().equals(type.getLocalPart())) {\r
410                                                                 map.map(a, attribute);\r
411                                                         }\r
412                                                 }\r
413                                         }\r
414                                 }\r
415                                 if (composition.getAttribute().size() == map.size()) {\r
416                                         handled.addAll(map.getRightSet());\r
417                                         handleAttributeComposition(obj, composition, map);      \r
418                                 }\r
419                         }\r
420                 }\r
421                 return handled;\r
422         }\r
423         \r
424         protected QName getBaseType(Attribute attribute) {\r
425                 if (attribute.getType() != null)\r
426                         return attribute.getType();\r
427                 if (attribute.getRef() != null)\r
428                         return attribute.getRef();\r
429                 SimpleType simpleType = attribute.getSimpleType();\r
430                 if (simpleType != null) {\r
431                         Restriction restriction = simpleType.getRestriction();\r
432                         if (restriction != null)\r
433                                 if (restriction.getBase() != null)\r
434                                         return restriction.getBase();\r
435                 }\r
436                 return null;\r
437         }\r
438         \r
439         protected Attribute getRefAttribute(QName ref) {\r
440                 for (OpenAttrs attrs : schema.getSimpleTypeOrComplexTypeOrGroup()) {\r
441                         if (attrs instanceof TopLevelAttribute) {\r
442                                 TopLevelAttribute attribute = (TopLevelAttribute)attrs;\r
443                                 if (attribute.getName().equals(ref.getLocalPart()))\r
444                                         return attribute;\r
445                         }\r
446                 }\r
447                 return null;\r
448         }\r
449         \r
450         protected abstract void handleAttributeComposition(SchemaObject obj, AttributeComposition composition, BijectionMap<org.simantics.xml.sax.configuration.Attribute, Annotated> attributes);\r
451         \r
452         \r
453         \r
454         \r
455         protected void handleComplexType(SchemaObject complexType) {\r
456                 handleComplexTypeAttributes(complexType);\r
457                 handleComplexTypeExtension(complexType);\r
458                 handleExtensionAttributes(complexType);\r
459         }\r
460         \r
461         protected abstract void handleIndicator(SchemaObject parent, SchemaElement indicator, SchemaElement element, boolean reference, String refName, QName refType);\r
462         protected abstract void handleIndicator(SchemaObject parent, SchemaElement indicator, SchemaElement element, boolean reference, String refName, OpenAttrs ref);\r
463         protected abstract void handleIndicator(SchemaObject parent, SchemaElement indicator, SchemaElement any);\r
464         protected abstract void handle(SchemaObject parent, SchemaElement indicator, List<SchemaElement> elements);\r
465         \r
466         protected void handle(SchemaObject parent, ExplicitGroup eg, SchemaElement.ElementType indicator) {\r
467                 handle(parent, new SchemaElement(eg, indicator));\r
468         }\r
469         \r
470         protected void handle(SchemaObject parent, SchemaElement indicator) {\r
471                 \r
472                 \r
473                 List<SchemaElement> elements = new ArrayList<SchemaElement>();\r
474                 List<SchemaElement> choices = new ArrayList<SchemaElement>();\r
475                 List<SchemaElement> sequences = new ArrayList<SchemaElement>();\r
476                 List<SchemaElement> alls = new ArrayList<SchemaElement>();\r
477                 List<SchemaElement> anys = new ArrayList<SchemaElement>();\r
478                 \r
479                 for (Object o : indicator.getGroup().getParticle()) {\r
480                         if (o instanceof JAXBElement<?>) {\r
481                                 JAXBElement<?> element = (JAXBElement<?>)o;\r
482                                 Object elemValue = element.getValue();\r
483                                 if (elemValue instanceof LocalElement) {\r
484                                         LocalElement localElement = (LocalElement)elemValue;\r
485                                         \r
486                                         elements.add(new SchemaElement(indicator,localElement, ElementType.ELEMENT));\r
487                                 } else if (elemValue instanceof All) {\r
488                                         alls.add(new SchemaElement(indicator,(All)elemValue, ElementType.ALL));\r
489                                 } else if (elemValue instanceof ExplicitGroup) {\r
490                                         QName qname = element.getName();\r
491                                         if ("choice".equals(qname.getLocalPart())) {\r
492                                                 choices.add(new SchemaElement(indicator,(ExplicitGroup)elemValue, ElementType.CHOICE));\r
493                                         } else if ("sequence".equals(qname.getLocalPart())) {\r
494                                                 sequences.add(new SchemaElement(indicator,(ExplicitGroup)elemValue, ElementType.SEQUENCE));\r
495                                         }\r
496                                 } else {\r
497                                         throw new RuntimeException("Unknown ExplicitGroup element " + elemValue.getClass().getName());\r
498                                 }\r
499                         } else if (o instanceof Any){\r
500                                 anys.add(new SchemaElement(indicator,(Any)o, ElementType.ANY));\r
501                         } else {\r
502                                 throw new RuntimeException("Unknown ExplicitGroup reference " + o.getClass().getName());\r
503                         }\r
504                 }\r
505                 \r
506                 if (elements.size() == 0 && choices.size() == 0 && sequences.size() == 0 && alls.size() == 0 && anys.size() == 0) {\r
507                         return;\r
508                 }\r
509                 \r
510                 if (indicator.getType() == SchemaElement.ElementType.SEQUENCE) {\r
511                         if (indicator.getRestriction().single()) {\r
512                                 if (elements.size() > 0) {\r
513                                         for (SchemaElement e : sequences) {\r
514                                                 handle(parent, e);\r
515                                         }\r
516                                         for (SchemaElement c : choices) {\r
517                                                 handle(parent, c);\r
518                                         }\r
519                                         \r
520                                         for (SchemaElement c : alls) {\r
521                                                 handle(parent, c);\r
522                                         }\r
523                                         handle(parent, indicator, elements);\r
524                                         for (SchemaElement a : anys) {\r
525                                                 handleIndicator(parent, indicator, a);\r
526                                         }\r
527                                 } else {\r
528                                         if (sequences.size() > 0) {\r
529                                                 throw new RuntimeException("Cannot handle Sequence with inner Sequences");\r
530                                         }\r
531                                         for (SchemaElement c : choices) {\r
532                                                 handle(parent, c);\r
533                                         }\r
534                                         for (SchemaElement a : anys) {\r
535                                                 handleIndicator(parent, indicator, a);\r
536                                         }\r
537                                 }\r
538                         } else {\r
539                                 if (sequences.size() > 0 || choices.size() > 0 || alls.size() > 0) {\r
540                                         throw new RuntimeException("Cannot handle Sequence with inner ExplicitGroups");\r
541                                 }\r
542                                 handle(parent, indicator, elements);\r
543                                 for (SchemaElement a : anys) {\r
544                                         handleIndicator(parent, indicator, a);\r
545                                 }\r
546                         }\r
547                 \r
548                 } else if (indicator.getType() == SchemaElement.ElementType.CHOICE){\r
549                         if (indicator.getRestriction().single()) {\r
550                                 if (sequences.size()> 0 || choices.size() > 0 || alls.size() > 0 || anys.size() > 0) {\r
551                                         throw new RuntimeException("Cannot handle Choice that contains something else than Elements");\r
552                                 }\r
553                                 handle(parent, indicator, elements);\r
554                                 \r
555                         } else {\r
556                                 if (sequences.size() > 0 || choices.size() > 0) {\r
557                                         throw new RuntimeException("Cannot handle Choice with inner ExplicitGroups");\r
558                                 }\r
559                                 handle(parent, indicator,  elements);\r
560                                 for (SchemaElement a : anys) {\r
561                                         handleIndicator(parent, indicator, a);\r
562                                 }\r
563                         }\r
564                 } else if (indicator.getType() == ElementType.ALL) {\r
565                         if (sequences.size()> 0 || choices.size() > 0 || alls.size() > 0 || anys.size() > 0) {\r
566                                 throw new RuntimeException("Cannot handle All that contains something else than Elements");\r
567                         }\r
568                         if (!indicator.getRestriction().single()) {\r
569                                 throw new RuntimeException("All indicator must have maxOccurs=1");\r
570                         }\r
571                         handle(parent, indicator, elements);\r
572                 }\r
573         }\r
574         \r
575         \r
576         protected void handle(SchemaObject parent, SchemaElement indicator, SchemaElement element) {\r
577                 Element localElement = element.getElement();\r
578                 if (localElement.getName() != null) {\r
579                         String refName = localElement.getName();\r
580                         QName refType = localElement.getType();\r
581                         if (refType != null)\r
582                                 handleIndicator(parent, indicator, element, false, refName, refType);\r
583                         else {\r
584                                 handleElement(elements.get(localElement));\r
585                                 handleIndicator(parent, indicator, element, false, refName, localElement);\r
586                                 //FIXME:\r
587                         }\r
588                 } else if (localElement.getRef() != null) {\r
589                         QName refType = localElement.getRef();\r
590                         handleIndicator(parent, indicator,element, true, refType.getLocalPart(), refType);\r
591                 }\r
592         }\r
593         \r
594         protected String getElementName(Element localElement) {\r
595                 if (localElement.getName() != null) {\r
596                         String refName = localElement.getName();\r
597                         QName refType = localElement.getType();\r
598                         if (refType != null)\r
599                                 return refName;\r
600                 } else if (localElement.getRef() != null) {\r
601                         QName refType = localElement.getRef();\r
602                         if (refType != null)\r
603                                 return refType.getLocalPart();\r
604                 }\r
605                 return null;\r
606         }\r
607         \r
608         protected String getChoiceName(List<SchemaElement> elements) {\r
609                 if (elements.size() == 1) {\r
610                         return getElementName(elements.get(0).getElement());\r
611                 }\r
612                 List<String> names = new ArrayList<String>();\r
613                 for (SchemaElement e : elements) {\r
614                         String name = getElementName(e.getElement());\r
615                         if (name != null)\r
616                                 names.add(name);\r
617                 }\r
618                 String name = "";\r
619                 for (int i = 0; i < names.size(); i++) {\r
620                         if (i == 0)\r
621                                 name = names.get(i);\r
622                         else\r
623                                 name += "Or"+names.get(i);\r
624                 }\r
625                 return name;\r
626         }\r
627         \r
628         \r
629         protected abstract void handle(SchemaObject parent, Attribute attribute) ;\r
630         protected abstract void handle(SchemaObject parent, AttributeGroup attribute) ;\r
631         \r
632         protected abstract void handleSimpleType(SchemaObject parent, SchemaObject simpleType);\r
633         \r
634         \r
635         \r
636         protected void handleComplexTypeExtension(SchemaObject complexTypeObj) {\r
637                 ComplexType complexType = complexTypeObj.getComplexType();\r
638                 if (complexType != null) {\r
639                         if (complexType.getChoice() != null)\r
640                                 handle(complexTypeObj, complexType.getChoice(), SchemaElement.ElementType.CHOICE);\r
641                         if (complexType.getSequence() != null)\r
642                                 handle(complexTypeObj, complexType.getSequence(), SchemaElement.ElementType.SEQUENCE);\r
643                         if (complexType.getAll() != null)\r
644                                 handle(complexTypeObj, complexType.getAll(), SchemaElement.ElementType.ALL);\r
645                         if (complexType.getGroup() != null)\r
646                                 throw new RuntimeException("Groups not supported");\r
647                         ComplexContent complexContent = complexType.getComplexContent();\r
648                         if (complexContent != null) {\r
649                                 ExtensionType extensionType = complexContent.getExtension();\r
650                                 if (extensionType != null) {\r
651                                         if (extensionType.getChoice() != null) {\r
652                                                 handle(complexTypeObj, extensionType.getChoice(), SchemaElement.ElementType.CHOICE);\r
653                                         }\r
654                                         if (extensionType.getSequence()!= null) {\r
655                                                 handle(complexTypeObj, extensionType.getSequence(), SchemaElement.ElementType.SEQUENCE);\r
656                                         }\r
657                                         if (extensionType.getAll()!= null) {\r
658                                                 handle(complexTypeObj, extensionType.getAll(), SchemaElement.ElementType.ALL);\r
659                                         }\r
660                                         if (extensionType.getGroup() != null) {\r
661                                                 throw new RuntimeException("Groups not supported");\r
662                                         }\r
663                                 }\r
664                         }\r
665                 }\r
666         }\r
667         \r
668         protected void handleElement(SchemaObject topLevelElement) {\r
669                 LocalComplexType complexType = topLevelElement.getElement().getComplexType();\r
670                 \r
671                 if (complexType != null) {\r
672                         SchemaObject complextTypeObj = complexTypes.get(complexType);\r
673                         handleElementComplexTypeAttributes(complextTypeObj);\r
674                         handleComplexTypeExtension(complextTypeObj);\r
675                 }\r
676                 \r
677                 \r
678         }\r
679         \r
680         \r
681         protected boolean isElementRef(String ref) {\r
682 //              for (OpenAttrs attrs : schema.getSimpleTypeOrComplexTypeOrGroup()) {\r
683 //                      if (attrs instanceof TopLevelElement) {\r
684 //                              TopLevelElement element = (TopLevelElement)attrs;\r
685 //                              if (ref.equals(element.getName()))\r
686 //                                      return true;\r
687 //                      }\r
688 //              }\r
689 //              return false;\r
690                 return elementName.containsKey(ref);\r
691         }\r
692         \r
693         protected boolean isComplexTypeRef(String ref) {\r
694 //              for (OpenAttrs attrs : schema.getSimpleTypeOrComplexTypeOrGroup()) {\r
695 //                      if (attrs instanceof TopLevelComplexType) {\r
696 //                              TopLevelComplexType element = (TopLevelComplexType)attrs;\r
697 //                              if (ref.equals(element.getName()))\r
698 //                                      return true;\r
699 //                      }\r
700 //              }\r
701 //              return false;\r
702                 return complexTypeName.containsKey(ref);\r
703                 \r
704         }\r
705         \r
706         protected NamedAttributeGroup getAttributeGroup(String name) {\r
707                 for (OpenAttrs attrs : schema.getSimpleTypeOrComplexTypeOrGroup()) {\r
708                         if (attrs instanceof NamedAttributeGroup) {\r
709                                 NamedAttributeGroup group = (NamedAttributeGroup)attrs;\r
710                                 if (group.getName().equals(name))\r
711                                         return group;\r
712                         }\r
713                 }\r
714                 return null;\r
715         }\r
716         \r
717         protected IDProvider getIDProvider(Element element) {\r
718                 List<IDProvider> idProviders = new ArrayList<IDProvider>(2);\r
719                 for (JAXBElement<?> e : configuration.getConversionRule()) {\r
720                         if (e.getValue() instanceof IDProvider) {\r
721                                 IDProvider ref = (IDProvider)e.getValue();\r
722                                 org.simantics.xml.sax.configuration.Element element2 = ref.getElement();\r
723                                 if (element2 != null) {\r
724                                         if (element.getName().equals(element2.getName()))\r
725                                                 idProviders.add(ref);\r
726                                 }\r
727                                 \r
728                         }\r
729                 }\r
730                 if (idProviders.size() == 0)\r
731                         return null;\r
732                 if (idProviders.size() > 1)\r
733                         throw new RuntimeException("Element " + element.getName() + " contains " + idProviders.size() + " id provider rules, only one is allowed.");\r
734                 return idProviders.get(0);\r
735         }\r
736         \r
737         protected IDProvider getIDProvider(ComplexType complexType) {\r
738                 List<IDProvider> idProviders = new ArrayList<IDProvider>(2);\r
739                 for (JAXBElement<?> e : configuration.getConversionRule()) {\r
740                         if (e.getValue() instanceof IDProvider) {\r
741                                 IDProvider ref = (IDProvider)e.getValue();\r
742                                 org.simantics.xml.sax.configuration.ComplexType complexType2 = ref.getComplexType();\r
743                                 if (complexType2 != null) {\r
744                                         if (complexType.getName().equals(complexType2.getName()))\r
745                                                 idProviders.add(ref);\r
746                                 }\r
747 \r
748                         }\r
749                 }\r
750                 if (idProviders.size() == 0)\r
751                         return null;\r
752                 if (idProviders.size() > 1)\r
753                         throw new RuntimeException("Element " + complexType.getName() + " contains " + idProviders.size() + " id provider rules, only one is allowed.");\r
754                 return idProviders.get(0);\r
755         }\r
756         \r
757         protected List<IDReference> getIDReferences(Element element) {\r
758                 List<IDReference> idReferences = new ArrayList<IDReference>(2);\r
759                 for (JAXBElement<?> e : configuration.getConversionRule()) {\r
760                         if (e.getValue() instanceof IDReference) {\r
761                                 IDReference ref = (IDReference)e.getValue();\r
762                                 org.simantics.xml.sax.configuration.Element element2 = ref.getElement();\r
763                                 if (element2 != null) {\r
764                                         if (element.getName().equals(element2.getName()))\r
765                                                 idReferences.add(ref);\r
766                                 }\r
767                         }\r
768                 }\r
769                 return idReferences;\r
770         }\r
771         \r
772         protected List<IDReference> getIDReferences(ComplexType complexType) {\r
773                 List<IDReference> idReferences = new ArrayList<IDReference>(2);\r
774                 for (JAXBElement<?> e : configuration.getConversionRule()) {\r
775                         if (e.getValue() instanceof IDReference) {\r
776                                 IDReference ref = (IDReference)e.getValue();\r
777                                 org.simantics.xml.sax.configuration.ComplexType complexType2 = ref.getComplexType();\r
778                                 if (complexType2 != null) {\r
779                                         if (complexType.getName().equals(complexType2.getName()))\r
780                                                 idReferences.add(ref);\r
781                                 }\r
782                         }\r
783                 }\r
784                 return idReferences;\r
785         }\r
786         \r
787         public UnrecognizedChildElement getUnknown(ComplexType complexType) {\r
788                 for (JAXBElement<?> e : configuration.getConversionRule()) {\r
789                         if (e.getValue() instanceof UnrecognizedChildElement) {\r
790                                 UnrecognizedChildElement ref = (UnrecognizedChildElement)e.getValue();\r
791                                 org.simantics.xml.sax.configuration.ComplexType complexType2 = ref.getComplexType();\r
792                                 if (complexType2 != null) {\r
793                                         if (complexType.getName().equals(complexType2.getName()))\r
794                                                 return ref;\r
795                                 }\r
796                         }\r
797                 }\r
798                 return null;\r
799         }\r
800         \r
801         public UnrecognizedChildElement getUnknown(Element element) {\r
802                 for (JAXBElement<?> e : configuration.getConversionRule()) {\r
803                         if (e.getValue() instanceof UnrecognizedChildElement) {\r
804                                 UnrecognizedChildElement ref = (UnrecognizedChildElement)e.getValue();\r
805                                 org.simantics.xml.sax.configuration.Element element2 = ref.getElement();\r
806                                 if (element2 != null) {\r
807                                         if (element.getName().equals(element2.getName()))\r
808                                                 return ref;\r
809                                 }\r
810                         }\r
811                 }\r
812                 return null;\r
813         }\r
814         \r
815         \r
816         public boolean useOriginalList(SchemaObject parent, SchemaElement indicator, SchemaElement element,  boolean reference, String ref, QName refType) {\r
817                 if (parent.getName() == null)\r
818                         parent = parent.getParent();\r
819                 if (parent.getName().contains("PipingNetworkSegment"))\r
820                         System.out.println();\r
821                 for (JAXBElement<?> e : configuration.getConversionRule()) {\r
822                         if (e.getValue() instanceof OrderedChild) {\r
823                                 OrderedChild oc = (OrderedChild)e.getValue();\r
824                                 org.simantics.xml.sax.configuration.Element element2 = oc.getElement();\r
825                                 org.simantics.xml.sax.configuration.ComplexType complexType = oc.getComplexType();\r
826                                 org.simantics.xml.sax.configuration.Element child = oc.getChild();\r
827                                 if (!oc.getType().equals("original"))\r
828                                         continue;\r
829                                 boolean match = false;\r
830                                 if (element2 != null) {\r
831                                         if (parent.getType() == ObjectType.ELEMENT && parent.getName().equals(element2.getName())) {\r
832                                                 match = true;\r
833                                         }\r
834                                 } else if (complexType != null) {\r
835                                         if (parent.getType() == ObjectType.COMPLEX_TYPE && parent.getName() != null && parent.getName().equals(complexType.getName())) {\r
836                                                 match = true;\r
837                                         }\r
838                                         \r
839                                 }\r
840                                 if (match) {\r
841                                         if (child != null) {\r
842                                                 if (matchChild(child, ref, refType)) {\r
843                                                         if (oc.getValue().equals("disable"))\r
844                                                                 return false;\r
845                                                         else return true;\r
846                                                 }\r
847                                         } else { \r
848                                                 if (oc.getValue().equals("disable"))\r
849                                                         return false;\r
850                                                 return true;\r
851                                         }\r
852                                         \r
853                                 }\r
854                         }\r
855                 }\r
856                 return indicator.order();\r
857         }\r
858         \r
859         public boolean useElementList(SchemaObject parent, SchemaElement indicator, SchemaElement element,  boolean reference, String refName, QName refType) {\r
860                 if (parent.getName() == null)\r
861                         parent = parent.getParent();\r
862                 if (parent.getName() == "PipingNetworkSegment")\r
863                         System.out.println();\r
864                 for (JAXBElement<?> e : configuration.getConversionRule()) {\r
865                         if (e.getValue() instanceof OrderedChild) {\r
866                                 OrderedChild oc = (OrderedChild)e.getValue();\r
867                                 org.simantics.xml.sax.configuration.Element element2 = oc.getElement();\r
868                                 org.simantics.xml.sax.configuration.ComplexType complexType = oc.getComplexType();\r
869                                 org.simantics.xml.sax.configuration.Element child = oc.getChild();\r
870                                 if (!oc.getType().equals("child"))\r
871                                         continue;\r
872                                 boolean match = false;\r
873                                 if (element2 != null) {\r
874                                         if (parent.getType() == ObjectType.ELEMENT && parent.getName().equals(element2.getName())) {\r
875                                                 match = true;\r
876                                         }\r
877                                 } else if (complexType != null) {\r
878                                         if (parent.getType() == ObjectType.COMPLEX_TYPE && parent.getName() != null && parent.getName().equals(complexType.getName())) {\r
879                                                 match = true;\r
880                                         }\r
881                                         \r
882                                 }\r
883                                 if (match) {\r
884                                         if (child != null) {\r
885                                                 if (matchChild(child, refName, refType)) {\r
886                                                         if (oc.getValue().equals("disable"))\r
887                                                                 return false;\r
888                                                         else return true;\r
889                                                 }\r
890                                         } else {\r
891                                                 if (oc.getValue().equals("disable"))\r
892                                                         return false;\r
893                                                 return true;\r
894                                         }\r
895                                         \r
896                                 }\r
897                         }\r
898                 }\r
899                 return element.many() && element.order();\r
900         }\r
901         \r
902         private boolean matchChild(org.simantics.xml.sax.configuration.Element child, String refName, QName refType) {\r
903                 if (refType != null && refType.getLocalPart().equals(child.getName()))\r
904                         return true;\r
905                 if (refName != null && refName.equals(child.getName()))\r
906                         return true;\r
907                 return false;\r
908         }\r
909         \r
910         public static class TypeEntry {\r
911                 String l0Type;\r
912                 String binding;\r
913                 String javaType;\r
914                 String defaultValue;\r
915                 boolean id;\r
916                 public TypeEntry(String l0Type, String binding, String javaType, String defaultValue) {\r
917                         super();\r
918                         this.l0Type = l0Type;\r
919                         this.binding = binding;\r
920                         this.javaType = javaType;\r
921                         this.defaultValue = defaultValue;\r
922                         this.id = false;\r
923                 }\r
924                 \r
925                 public TypeEntry(String l0Type, String binding, String javaType, String defaultValue, boolean id) {\r
926                         super();\r
927                         this.l0Type = l0Type;\r
928                         this.binding = binding;\r
929                         this.javaType = javaType;\r
930                         this.defaultValue = defaultValue;\r
931                         this.id = id;\r
932                 }\r
933                 \r
934         }\r
935 \r
936 }\r