]> gerrit.simantics Code Review - simantics/interop.git/blob - org.simantics.xml.sax/src/org/simantics/xml/sax/SchemaConversionBase.java
Schema conversion updates (necessary for Proteus PID Profile schema)
[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 QName getPrimitiveType(Attribute attribute) {\r
440                 QName type = getBaseType(attribute);\r
441                 String b = getBindingFromPrimitiveType(type);\r
442                 while (b==null && type != null) {\r
443                         SchemaObject baseType = simpleTypeName.get(type.getLocalPart());\r
444                         if (baseType != null) {\r
445                                 Restriction restriction = baseType.getSimpleType().getRestriction();\r
446                                 if (restriction != null)\r
447                                         if (restriction.getBase() != null) {\r
448                                                 type = restriction.getBase();\r
449                                                 b = getBindingFromPrimitiveType(type);\r
450                                         }\r
451                         }\r
452                 }\r
453                 return type;\r
454         }\r
455         \r
456         protected Attribute getRefAttribute(QName ref) {\r
457                 for (OpenAttrs attrs : schema.getSimpleTypeOrComplexTypeOrGroup()) {\r
458                         if (attrs instanceof TopLevelAttribute) {\r
459                                 TopLevelAttribute attribute = (TopLevelAttribute)attrs;\r
460                                 if (attribute.getName().equals(ref.getLocalPart()))\r
461                                         return attribute;\r
462                         }\r
463                 }\r
464                 return null;\r
465         }\r
466         \r
467         protected abstract void handleAttributeComposition(SchemaObject obj, AttributeComposition composition, BijectionMap<org.simantics.xml.sax.configuration.Attribute, Annotated> attributes);\r
468         \r
469         \r
470         \r
471         \r
472         protected void handleComplexType(SchemaObject complexType) {\r
473                 handleComplexTypeAttributes(complexType);\r
474                 handleComplexTypeExtension(complexType);\r
475                 handleExtensionAttributes(complexType);\r
476         }\r
477         \r
478         protected abstract void handleIndicator(SchemaObject parent, SchemaElement indicator, SchemaElement element, boolean reference, String refName, QName refType);\r
479         protected abstract void handleIndicator(SchemaObject parent, SchemaElement indicator, SchemaElement element, boolean reference, String refName, OpenAttrs ref);\r
480         protected abstract void handleIndicator(SchemaObject parent, SchemaElement indicator, SchemaElement any);\r
481         protected abstract void handle(SchemaObject parent, SchemaElement indicator, List<SchemaElement> elements);\r
482         \r
483         protected void handle(SchemaObject parent, ExplicitGroup eg, SchemaElement.ElementType indicator) {\r
484                 handle(parent, new SchemaElement(eg, indicator));\r
485         }\r
486         \r
487         protected void handle(SchemaObject parent, SchemaElement indicator) {\r
488                 \r
489                 \r
490                 List<SchemaElement> elements = new ArrayList<SchemaElement>();\r
491                 List<SchemaElement> choices = new ArrayList<SchemaElement>();\r
492                 List<SchemaElement> sequences = new ArrayList<SchemaElement>();\r
493                 List<SchemaElement> alls = new ArrayList<SchemaElement>();\r
494                 List<SchemaElement> anys = new ArrayList<SchemaElement>();\r
495                 \r
496                 for (Object o : indicator.getGroup().getParticle()) {\r
497                         if (o instanceof JAXBElement<?>) {\r
498                                 JAXBElement<?> element = (JAXBElement<?>)o;\r
499                                 Object elemValue = element.getValue();\r
500                                 if (elemValue instanceof LocalElement) {\r
501                                         LocalElement localElement = (LocalElement)elemValue;\r
502                                         \r
503                                         elements.add(new SchemaElement(indicator,localElement, ElementType.ELEMENT));\r
504                                 } else if (elemValue instanceof All) {\r
505                                         alls.add(new SchemaElement(indicator,(All)elemValue, ElementType.ALL));\r
506                                 } else if (elemValue instanceof ExplicitGroup) {\r
507                                         QName qname = element.getName();\r
508                                         if ("choice".equals(qname.getLocalPart())) {\r
509                                                 choices.add(new SchemaElement(indicator,(ExplicitGroup)elemValue, ElementType.CHOICE));\r
510                                         } else if ("sequence".equals(qname.getLocalPart())) {\r
511                                                 sequences.add(new SchemaElement(indicator,(ExplicitGroup)elemValue, ElementType.SEQUENCE));\r
512                                         }\r
513                                 } else {\r
514                                         throw new RuntimeException("Unknown ExplicitGroup element " + elemValue.getClass().getName());\r
515                                 }\r
516                         } else if (o instanceof Any){\r
517                                 anys.add(new SchemaElement(indicator,(Any)o, ElementType.ANY));\r
518                         } else {\r
519                                 throw new RuntimeException("Unknown ExplicitGroup reference " + o.getClass().getName());\r
520                         }\r
521                 }\r
522                 \r
523                 if (elements.size() == 0 && choices.size() == 0 && sequences.size() == 0 && alls.size() == 0 && anys.size() == 0) {\r
524                         return;\r
525                 }\r
526                 \r
527                 if (indicator.getType() == SchemaElement.ElementType.SEQUENCE) {\r
528                         if (indicator.getRestriction().single()) {\r
529                                 if (elements.size() > 0) {\r
530                                         for (SchemaElement e : sequences) {\r
531                                                 handle(parent, e);\r
532                                         }\r
533                                         for (SchemaElement c : choices) {\r
534                                                 handle(parent, c);\r
535                                         }\r
536                                         \r
537                                         for (SchemaElement c : alls) {\r
538                                                 handle(parent, c);\r
539                                         }\r
540                                         handle(parent, indicator, elements);\r
541                                         for (SchemaElement a : anys) {\r
542                                                 handleIndicator(parent, indicator, a);\r
543                                         }\r
544                                 } else {\r
545                                         if (sequences.size() > 0) {\r
546                                                 throw new RuntimeException("Cannot handle Sequence with inner Sequences");\r
547                                         }\r
548                                         for (SchemaElement c : choices) {\r
549                                                 handle(parent, c);\r
550                                         }\r
551                                         for (SchemaElement a : anys) {\r
552                                                 handleIndicator(parent, indicator, a);\r
553                                         }\r
554                                 }\r
555                         } else {\r
556                                 if (sequences.size() > 0 || choices.size() > 0 || alls.size() > 0) {\r
557                                         throw new RuntimeException("Cannot handle Sequence 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                 \r
565                 } else if (indicator.getType() == SchemaElement.ElementType.CHOICE){\r
566                         if (indicator.getRestriction().single()) {\r
567                                 if (sequences.size()> 0 || choices.size() > 0 || alls.size() > 0 || anys.size() > 0) {\r
568                                         throw new RuntimeException("Cannot handle Choice that contains something else than Elements");\r
569                                 }\r
570                                 handle(parent, indicator, elements);\r
571                                 \r
572                         } else {\r
573                                 if (sequences.size() > 0 || choices.size() > 0) {\r
574                                         throw new RuntimeException("Cannot handle Choice with inner ExplicitGroups");\r
575                                 }\r
576                                 handle(parent, indicator,  elements);\r
577                                 for (SchemaElement a : anys) {\r
578                                         handleIndicator(parent, indicator, a);\r
579                                 }\r
580                         }\r
581                 } else if (indicator.getType() == ElementType.ALL) {\r
582                         if (sequences.size()> 0 || choices.size() > 0 || alls.size() > 0 || anys.size() > 0) {\r
583                                 throw new RuntimeException("Cannot handle All that contains something else than Elements");\r
584                         }\r
585                         if (!indicator.getRestriction().single()) {\r
586                                 throw new RuntimeException("All indicator must have maxOccurs=1");\r
587                         }\r
588                         handle(parent, indicator, elements);\r
589                 }\r
590         }\r
591         \r
592         \r
593         protected void handle(SchemaObject parent, SchemaElement indicator, SchemaElement element) {\r
594                 Element localElement = element.getElement();\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                                 handleIndicator(parent, indicator, element, false, refName, refType);\r
600                         else {\r
601                                 handleElement(elements.get(localElement));\r
602                                 handleIndicator(parent, indicator, element, false, refName, localElement);\r
603                                 //FIXME:\r
604                         }\r
605                 } else if (localElement.getRef() != null) {\r
606                         QName refType = localElement.getRef();\r
607                         handleIndicator(parent, indicator,element, true, refType.getLocalPart(), refType);\r
608                 }\r
609         }\r
610         \r
611         protected String getElementName(Element localElement) {\r
612                 if (localElement.getName() != null) {\r
613                         String refName = localElement.getName();\r
614                         QName refType = localElement.getType();\r
615                         if (refType != null)\r
616                                 return refName;\r
617                 } else if (localElement.getRef() != null) {\r
618                         QName refType = localElement.getRef();\r
619                         if (refType != null)\r
620                                 return refType.getLocalPart();\r
621                 }\r
622                 return null;\r
623         }\r
624         \r
625         protected String getChoiceName(List<SchemaElement> elements) {\r
626                 if (elements.size() == 1) {\r
627                         return getElementName(elements.get(0).getElement());\r
628                 }\r
629                 List<String> names = new ArrayList<String>();\r
630                 for (SchemaElement e : elements) {\r
631                         String name = getElementName(e.getElement());\r
632                         if (name != null)\r
633                                 names.add(name);\r
634                 }\r
635                 String name = "";\r
636                 for (int i = 0; i < names.size(); i++) {\r
637                         if (i == 0)\r
638                                 name = names.get(i);\r
639                         else\r
640                                 name += "Or"+names.get(i);\r
641                 }\r
642                 return name;\r
643         }\r
644         \r
645         \r
646         protected abstract void handle(SchemaObject parent, Attribute attribute) ;\r
647         protected abstract void handle(SchemaObject parent, AttributeGroup attribute) ;\r
648         \r
649         protected abstract void handleSimpleType(SchemaObject parent, SchemaObject simpleType);\r
650         \r
651         \r
652         \r
653         protected void handleComplexTypeExtension(SchemaObject complexTypeObj) {\r
654                 ComplexType complexType = complexTypeObj.getComplexType();\r
655                 if (complexType != null) {\r
656                         if (complexType.getChoice() != null)\r
657                                 handle(complexTypeObj, complexType.getChoice(), SchemaElement.ElementType.CHOICE);\r
658                         if (complexType.getSequence() != null)\r
659                                 handle(complexTypeObj, complexType.getSequence(), SchemaElement.ElementType.SEQUENCE);\r
660                         if (complexType.getAll() != null)\r
661                                 handle(complexTypeObj, complexType.getAll(), SchemaElement.ElementType.ALL);\r
662                         if (complexType.getGroup() != null)\r
663                                 throw new RuntimeException("Groups not supported");\r
664                         ComplexContent complexContent = complexType.getComplexContent();\r
665                         if (complexContent != null) {\r
666                                 ExtensionType extensionType = complexContent.getExtension();\r
667                                 if (extensionType != null) {\r
668                                         if (extensionType.getChoice() != null) {\r
669                                                 handle(complexTypeObj, extensionType.getChoice(), SchemaElement.ElementType.CHOICE);\r
670                                         }\r
671                                         if (extensionType.getSequence()!= null) {\r
672                                                 handle(complexTypeObj, extensionType.getSequence(), SchemaElement.ElementType.SEQUENCE);\r
673                                         }\r
674                                         if (extensionType.getAll()!= null) {\r
675                                                 handle(complexTypeObj, extensionType.getAll(), SchemaElement.ElementType.ALL);\r
676                                         }\r
677                                         if (extensionType.getGroup() != null) {\r
678                                                 throw new RuntimeException("Groups not supported");\r
679                                         }\r
680                                 }\r
681                         }\r
682                 }\r
683         }\r
684         \r
685         protected void handleElement(SchemaObject topLevelElement) {\r
686                 LocalComplexType complexType = topLevelElement.getElement().getComplexType();\r
687                 \r
688                 if (complexType != null) {\r
689                         SchemaObject complextTypeObj = complexTypes.get(complexType);\r
690                         handleElementComplexTypeAttributes(complextTypeObj);\r
691                         handleComplexTypeExtension(complextTypeObj);\r
692                 }\r
693                 \r
694                 \r
695         }\r
696         \r
697         \r
698         protected boolean isElementRef(String ref) {\r
699 //              for (OpenAttrs attrs : schema.getSimpleTypeOrComplexTypeOrGroup()) {\r
700 //                      if (attrs instanceof TopLevelElement) {\r
701 //                              TopLevelElement element = (TopLevelElement)attrs;\r
702 //                              if (ref.equals(element.getName()))\r
703 //                                      return true;\r
704 //                      }\r
705 //              }\r
706 //              return false;\r
707                 return elementName.containsKey(ref);\r
708         }\r
709         \r
710         protected boolean isComplexTypeRef(String ref) {\r
711 //              for (OpenAttrs attrs : schema.getSimpleTypeOrComplexTypeOrGroup()) {\r
712 //                      if (attrs instanceof TopLevelComplexType) {\r
713 //                              TopLevelComplexType element = (TopLevelComplexType)attrs;\r
714 //                              if (ref.equals(element.getName()))\r
715 //                                      return true;\r
716 //                      }\r
717 //              }\r
718 //              return false;\r
719                 return complexTypeName.containsKey(ref);\r
720                 \r
721         }\r
722         \r
723         protected NamedAttributeGroup getAttributeGroup(String name) {\r
724                 for (OpenAttrs attrs : schema.getSimpleTypeOrComplexTypeOrGroup()) {\r
725                         if (attrs instanceof NamedAttributeGroup) {\r
726                                 NamedAttributeGroup group = (NamedAttributeGroup)attrs;\r
727                                 if (group.getName().equals(name))\r
728                                         return group;\r
729                         }\r
730                 }\r
731                 return null;\r
732         }\r
733         \r
734         protected IDProvider getIDProvider(Element element) {\r
735                 List<IDProvider> idProviders = new ArrayList<IDProvider>(2);\r
736                 for (JAXBElement<?> e : configuration.getConversionRule()) {\r
737                         if (e.getValue() instanceof IDProvider) {\r
738                                 IDProvider ref = (IDProvider)e.getValue();\r
739                                 org.simantics.xml.sax.configuration.Element element2 = ref.getElement();\r
740                                 if (element2 != null) {\r
741                                         if (element.getName().equals(element2.getName()))\r
742                                                 idProviders.add(ref);\r
743                                 }\r
744                                 \r
745                         }\r
746                 }\r
747                 if (idProviders.size() == 0)\r
748                         return null;\r
749                 if (idProviders.size() > 1)\r
750                         throw new RuntimeException("Element " + element.getName() + " contains " + idProviders.size() + " id provider rules, only one is allowed.");\r
751                 return idProviders.get(0);\r
752         }\r
753         \r
754         protected IDProvider getIDProvider(ComplexType complexType) {\r
755                 List<IDProvider> idProviders = new ArrayList<IDProvider>(2);\r
756                 for (JAXBElement<?> e : configuration.getConversionRule()) {\r
757                         if (e.getValue() instanceof IDProvider) {\r
758                                 IDProvider ref = (IDProvider)e.getValue();\r
759                                 org.simantics.xml.sax.configuration.ComplexType complexType2 = ref.getComplexType();\r
760                                 if (complexType2 != null) {\r
761                                         if (complexType.getName().equals(complexType2.getName()))\r
762                                                 idProviders.add(ref);\r
763                                 }\r
764 \r
765                         }\r
766                 }\r
767                 if (idProviders.size() == 0)\r
768                         return null;\r
769                 if (idProviders.size() > 1)\r
770                         throw new RuntimeException("Element " + complexType.getName() + " contains " + idProviders.size() + " id provider rules, only one is allowed.");\r
771                 return idProviders.get(0);\r
772         }\r
773         \r
774         protected List<IDReference> getIDReferences(Element element) {\r
775                 List<IDReference> idReferences = new ArrayList<IDReference>(2);\r
776                 for (JAXBElement<?> e : configuration.getConversionRule()) {\r
777                         if (e.getValue() instanceof IDReference) {\r
778                                 IDReference ref = (IDReference)e.getValue();\r
779                                 org.simantics.xml.sax.configuration.Element element2 = ref.getElement();\r
780                                 if (element2 != null) {\r
781                                         if (element.getName().equals(element2.getName()))\r
782                                                 idReferences.add(ref);\r
783                                 }\r
784                         }\r
785                 }\r
786                 return idReferences;\r
787         }\r
788         \r
789         protected List<IDReference> getIDReferences(ComplexType complexType) {\r
790                 List<IDReference> idReferences = new ArrayList<IDReference>(2);\r
791                 for (JAXBElement<?> e : configuration.getConversionRule()) {\r
792                         if (e.getValue() instanceof IDReference) {\r
793                                 IDReference ref = (IDReference)e.getValue();\r
794                                 org.simantics.xml.sax.configuration.ComplexType complexType2 = ref.getComplexType();\r
795                                 if (complexType2 != null) {\r
796                                         if (complexType.getName().equals(complexType2.getName()))\r
797                                                 idReferences.add(ref);\r
798                                 }\r
799                         }\r
800                 }\r
801                 return idReferences;\r
802         }\r
803         \r
804         public UnrecognizedChildElement getUnknown(ComplexType complexType) {\r
805                 for (JAXBElement<?> e : configuration.getConversionRule()) {\r
806                         if (e.getValue() instanceof UnrecognizedChildElement) {\r
807                                 UnrecognizedChildElement ref = (UnrecognizedChildElement)e.getValue();\r
808                                 org.simantics.xml.sax.configuration.ComplexType complexType2 = ref.getComplexType();\r
809                                 if (complexType2 != null) {\r
810                                         if (complexType.getName().equals(complexType2.getName()))\r
811                                                 return ref;\r
812                                 }\r
813                         }\r
814                 }\r
815                 return null;\r
816         }\r
817         \r
818         public UnrecognizedChildElement getUnknown(Element element) {\r
819                 for (JAXBElement<?> e : configuration.getConversionRule()) {\r
820                         if (e.getValue() instanceof UnrecognizedChildElement) {\r
821                                 UnrecognizedChildElement ref = (UnrecognizedChildElement)e.getValue();\r
822                                 org.simantics.xml.sax.configuration.Element element2 = ref.getElement();\r
823                                 if (element2 != null) {\r
824                                         if (element.getName().equals(element2.getName()))\r
825                                                 return ref;\r
826                                 }\r
827                         }\r
828                 }\r
829                 return null;\r
830         }\r
831         \r
832         \r
833         public boolean useOriginalList(SchemaObject parent, SchemaElement indicator, SchemaElement element,  boolean reference, String ref, QName refType) {\r
834                 if (parent.getName() == null)\r
835                         parent = parent.getParent();\r
836                 if (parent.getName().contains("PipingNetworkSegment"))\r
837                         System.out.println();\r
838                 for (JAXBElement<?> e : configuration.getConversionRule()) {\r
839                         if (e.getValue() instanceof OrderedChild) {\r
840                                 OrderedChild oc = (OrderedChild)e.getValue();\r
841                                 org.simantics.xml.sax.configuration.Element element2 = oc.getElement();\r
842                                 org.simantics.xml.sax.configuration.ComplexType complexType = oc.getComplexType();\r
843                                 org.simantics.xml.sax.configuration.Element child = oc.getChild();\r
844                                 if (!oc.getType().equals("original"))\r
845                                         continue;\r
846                                 boolean match = false;\r
847                                 if (element2 != null) {\r
848                                         if (parent.getType() == ObjectType.ELEMENT && parent.getName().equals(element2.getName())) {\r
849                                                 match = true;\r
850                                         }\r
851                                 } else if (complexType != null) {\r
852                                         if (parent.getType() == ObjectType.COMPLEX_TYPE && parent.getName() != null && parent.getName().equals(complexType.getName())) {\r
853                                                 match = true;\r
854                                         }\r
855                                         \r
856                                 }\r
857                                 if (match) {\r
858                                         if (child != null) {\r
859                                                 if (matchChild(child, ref, refType)) {\r
860                                                         if (oc.getValue().equals("disable"))\r
861                                                                 return false;\r
862                                                         else return true;\r
863                                                 }\r
864                                         } else { \r
865                                                 if (oc.getValue().equals("disable"))\r
866                                                         return false;\r
867                                                 return true;\r
868                                         }\r
869                                         \r
870                                 }\r
871                         }\r
872                 }\r
873                 return indicator.order();\r
874         }\r
875         \r
876         public boolean useElementList(SchemaObject parent, SchemaElement indicator, SchemaElement element,  boolean reference, String refName, QName refType) {\r
877                 if (parent.getName() == null)\r
878                         parent = parent.getParent();\r
879                 if (parent.getName() == "PipingNetworkSegment")\r
880                         System.out.println();\r
881                 for (JAXBElement<?> e : configuration.getConversionRule()) {\r
882                         if (e.getValue() instanceof OrderedChild) {\r
883                                 OrderedChild oc = (OrderedChild)e.getValue();\r
884                                 org.simantics.xml.sax.configuration.Element element2 = oc.getElement();\r
885                                 org.simantics.xml.sax.configuration.ComplexType complexType = oc.getComplexType();\r
886                                 org.simantics.xml.sax.configuration.Element child = oc.getChild();\r
887                                 if (!oc.getType().equals("child"))\r
888                                         continue;\r
889                                 boolean match = false;\r
890                                 if (element2 != null) {\r
891                                         if (parent.getType() == ObjectType.ELEMENT && parent.getName().equals(element2.getName())) {\r
892                                                 match = true;\r
893                                         }\r
894                                 } else if (complexType != null) {\r
895                                         if (parent.getType() == ObjectType.COMPLEX_TYPE && parent.getName() != null && parent.getName().equals(complexType.getName())) {\r
896                                                 match = true;\r
897                                         }\r
898                                         \r
899                                 }\r
900                                 if (match) {\r
901                                         if (child != null) {\r
902                                                 if (matchChild(child, refName, refType)) {\r
903                                                         if (oc.getValue().equals("disable"))\r
904                                                                 return false;\r
905                                                         else return true;\r
906                                                 }\r
907                                         } else {\r
908                                                 if (oc.getValue().equals("disable"))\r
909                                                         return false;\r
910                                                 return true;\r
911                                         }\r
912                                         \r
913                                 }\r
914                         }\r
915                 }\r
916                 return element.many() && element.order();\r
917         }\r
918         \r
919         private boolean matchChild(org.simantics.xml.sax.configuration.Element child, String refName, QName refType) {\r
920                 if (refType != null && refType.getLocalPart().equals(child.getName()))\r
921                         return true;\r
922                 if (refName != null && refName.equals(child.getName()))\r
923                         return true;\r
924                 return false;\r
925         }\r
926         \r
927         public static class TypeEntry {\r
928                 String l0Type;\r
929                 String binding;\r
930                 String javaType;\r
931                 String defaultValue;\r
932                 boolean id;\r
933                 public TypeEntry(String l0Type, String binding, String javaType, String defaultValue) {\r
934                         super();\r
935                         this.l0Type = l0Type;\r
936                         this.binding = binding;\r
937                         this.javaType = javaType;\r
938                         this.defaultValue = defaultValue;\r
939                         this.id = false;\r
940                 }\r
941                 \r
942                 public TypeEntry(String l0Type, String binding, String javaType, String defaultValue, boolean id) {\r
943                         super();\r
944                         this.l0Type = l0Type;\r
945                         this.binding = binding;\r
946                         this.javaType = javaType;\r
947                         this.defaultValue = defaultValue;\r
948                         this.id = id;\r
949                 }\r
950                 \r
951         }\r
952 \r
953 }\r