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