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