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