]> gerrit.simantics Code Review - simantics/interop.git/blob - org.simantics.xml.sax/src/org/simantics/xml/sax/ImporterGenerator.java
Schema conversion updates (necessary for Proteus PID Profile schema)
[simantics/interop.git] / org.simantics.xml.sax / src / org / simantics / xml / sax / ImporterGenerator.java
1 package org.simantics.xml.sax;\r
2 \r
3 import java.io.File;\r
4 import java.io.IOException;\r
5 import java.io.PrintWriter;\r
6 import java.io.StringWriter;\r
7 import java.util.ArrayList;\r
8 import java.util.HashMap;\r
9 import java.util.List;\r
10 import java.util.Map;\r
11 \r
12 import javax.xml.namespace.QName;\r
13 \r
14 import org.simantics.utils.datastructures.BijectionMap;\r
15 import org.simantics.utils.datastructures.Pair;\r
16 import org.simantics.xml.sax.configuration.AttributeComposition;\r
17 import org.simantics.xml.sax.configuration.Configuration;\r
18 import org.simantics.xml.sax.configuration.IDProvider;\r
19 import org.simantics.xml.sax.configuration.IDReference;\r
20 import org.simantics.xml.sax.configuration.UnrecognizedChildElement;\r
21 import org.w3._2001.xmlschema.Annotated;\r
22 import org.w3._2001.xmlschema.Attribute;\r
23 import org.w3._2001.xmlschema.AttributeGroup;\r
24 import org.w3._2001.xmlschema.AttributeGroupRef;\r
25 import org.w3._2001.xmlschema.ComplexType;\r
26 import org.w3._2001.xmlschema.Element;\r
27 import org.w3._2001.xmlschema.LocalComplexType;\r
28 import org.w3._2001.xmlschema.LocalSimpleType;\r
29 import org.w3._2001.xmlschema.NamedAttributeGroup;\r
30 import org.w3._2001.xmlschema.OpenAttrs;\r
31 import org.w3._2001.xmlschema.Restriction;\r
32 import org.w3._2001.xmlschema.Schema;\r
33 import org.w3._2001.xmlschema.SimpleType;\r
34 import org.w3._2001.xmlschema.TopLevelAttribute;\r
35 \r
36 public class ImporterGenerator extends SchemaConversionBase{\r
37         \r
38         public ImporterGenerator(Configuration configuration) {\r
39                 super(configuration);\r
40         }\r
41 \r
42         String commentTag = "//";\r
43         \r
44         Schema schema;\r
45         String ontologyClassName;\r
46         SchemaConverter converter;\r
47         \r
48         List<String> ruleClassNames = new ArrayList<String>();\r
49         \r
50         String ontShort = "ONT"; \r
51         \r
52         File importParserDir;\r
53         String elementPackageName;\r
54         \r
55         public void createParser(Schema schema,String className, SchemaConverter converter) throws IOException {\r
56                 this.schema = schema;\r
57                 this.ontologyClassName = className;\r
58                 this.converter = converter;\r
59                 \r
60                 \r
61                 String packageParts[] = className.split("\\.");\r
62                 String name = packageParts[packageParts.length-1];\r
63         \r
64                 \r
65                 ontShort = name.substring(0, 3).toUpperCase();\r
66                 ontShort +=".";\r
67                 String parserPackagePostfix = "_elem";\r
68                 String importerClassPostfix = "Importer";\r
69                 elementPackageName = name+parserPackagePostfix;\r
70                 \r
71                 importParserDir= new File(converter.getParserDir().getAbsolutePath()+"/"+elementPackageName);\r
72                 if (!importParserDir.exists())\r
73                         importParserDir.mkdirs();\r
74                 \r
75                 handle(schema);\r
76                 \r
77                 File importParserFile = new File(converter.getParserDir().getAbsolutePath()+"/"+name+importerClassPostfix+".java");\r
78                 PrintWriter mainWriter = createFile(importParserFile);\r
79                 mainWriter.println("package " + converter.getPluginName() +";");\r
80                 mainWriter.println();\r
81                 mainWriter.println("import java.io.File;");\r
82                 mainWriter.println("import org.simantics.db.Session;");\r
83                 mainWriter.println("import org.simantics.xml.sax.base.AbstractImporter;");\r
84                 mainWriter.println("import org.simantics.xml.sax.base.XMLParser;");\r
85                 mainWriter.println();\r
86                 mainWriter.println("public class " + name + importerClassPostfix+" extends AbstractImporter {");\r
87                 mainWriter.println();\r
88                 mainWriter.println("   public " + name + importerClassPostfix+"(Session session, File file)  {");\r
89                 mainWriter.println("      super(session,file);");\r
90                 mainWriter.println("   }");\r
91                 mainWriter.println();\r
92                 mainWriter.println("   @Override");\r
93                 mainWriter.println("   public void configure(XMLParser parser) {");\r
94                 for (String s : ruleClassNames) {\r
95                 mainWriter.println("      parser.add(new "+s+"());");\r
96                 }\r
97                 mainWriter.println("   }");\r
98                 mainWriter.println("}");\r
99                 \r
100                 mainWriter.println();\r
101                 mainWriter.flush();\r
102                 mainWriter.close();\r
103         }\r
104         \r
105         protected PrintWriter createFile(File file) throws IOException {\r
106                 if (!file.exists())\r
107                         file.createNewFile();\r
108                 PrintWriter writer = new PrintWriter(file);\r
109                 for (String s : converter.getHeader()) {\r
110                         writer.println(commentTag + " " + s);   \r
111                 }\r
112                 writer.println();\r
113                 return writer;\r
114         }\r
115         \r
116         protected String getValueGetter(String binding,String name) {\r
117                 if (binding == null)\r
118                         return name+".getValue()";\r
119                 if ("STRING".equals(binding))\r
120                         return name+".getValue()";\r
121                 if ("BOOLEAN".equals(binding))\r
122                         return "Boolean.parseBoolean("+name+".getValue())";\r
123                 if ("INTEGER".equals(binding))\r
124                         return "Integer.parseInt("+name+".getValue())";\r
125                 if ("DOUBLE".equals(binding))\r
126                         return "Double.parseDouble("+name+".getValue())";\r
127                 if ("FLOAT".equals(binding))\r
128                         return "Float.parseFloat("+name+".getValue())";\r
129                 return name+".getValue()";\r
130         }\r
131         \r
132         protected String getValueGetter(String binding) {\r
133                 if (binding == null)\r
134                         return "value";\r
135                 if ("STRING".equals(binding))\r
136                         return "value";\r
137                 if ("BOOLEAN".equals(binding))\r
138                         return "Boolean.parseBoolean(value)";\r
139                 if ("INTEGER".equals(binding))\r
140                         return "Integer.parseInt(value)";\r
141                 if ("DOUBLE".equals(binding))\r
142                         return "Double.parseDouble(value)";\r
143                 if ("FLOAT".equals(binding))\r
144                         return "Float.parseFloat(value)";\r
145                 return "value";\r
146         }\r
147         \r
148         protected void handle(TopLevelAttribute topLevelAttribute) {\r
149 \r
150         }\r
151         \r
152 \r
153         \r
154         public static String getComplexTypePrefix() {\r
155                 return "ComplexTypes_";\r
156         }       \r
157         \r
158         public static String getAttributeGroupPrefix() {\r
159                 return "AttributeGroups_";\r
160         }\r
161         \r
162         private Map<SchemaObject, FileWriter> writers = new HashMap<SchemaObject, ImporterGenerator.FileWriter>();\r
163         @Override\r
164         protected void handleComplexType(SchemaObject complexTypeObj) {\r
165                 ComplexType topLevelComplexType = complexTypeObj.getComplexType();\r
166                 \r
167                 String name = getName(complexTypeObj);//topLevelComplexType.getName();\r
168                 \r
169                 String className = name;//"_"+name;\r
170                 \r
171                 FileWriter fw = new FileWriter();\r
172                 try {\r
173                         fw.writer = createFile(new File(importParserDir.getAbsolutePath()+"/"+className+".java"));\r
174                 } catch (IOException e) {\r
175                         throw new RuntimeException(e);\r
176                 }\r
177                 writers.put(complexTypeObj, fw);\r
178                 \r
179                 boolean isList = false;\r
180 \r
181                 String baseClass = "org.simantics.xml.sax.base.XMLElementNamedChildParserBase";\r
182                 \r
183                 boolean inherited = false;\r
184                 \r
185                 QName type = getComplexTypeBase(topLevelComplexType);\r
186                 if (type != null && !type.getNamespaceURI().equals("http://www.w3.org/2001/XMLSchema")) {\r
187                         baseClass = getName(complexTypeName.get(type.getLocalPart()));\r
188                         inherited = true;\r
189                 }\r
190                 \r
191                 provider = getIDProvider(topLevelComplexType);\r
192                 List<IDReference> references = getIDReferences(topLevelComplexType);\r
193                 UnrecognizedChildElement unknownChildElement = getUnknown(topLevelComplexType);\r
194 \r
195                 List<String> intrerfaces = new ArrayList<String>();\r
196                 if (references.size() > 0)\r
197                         intrerfaces.add("org.simantics.xml.sax.base.IDReferenceParser");\r
198                 if (unknownChildElement != null)\r
199                         intrerfaces.add("org.simantics.xml.sax.base.UnrecognizedElementParser");\r
200                 \r
201                 createClassHeader(fw.writer, isList);\r
202                 writeClass(fw.writer,true, null, className, baseClass, intrerfaces);\r
203                         \r
204                 writeIDProvider(fw.writer);\r
205         \r
206                 fw.writer.println("   @Override");\r
207                 fw.writer.println("   public Resource create(WriteGraph graph, Element element) throws DatabaseException{");\r
208                 fw.writer.println("      Layer0 L0 = Layer0.getInstance(graph);");\r
209                 fw.writer.println("      "+getOntologyImport());\r
210                 if (!isList) {\r
211                 fw.writer.println("      Resource res = graph.newResource();");\r
212                 fw.writer.println("      graph.claim(res, L0.InstanceOf, "+ontShort+name+");");\r
213                 } else {\r
214                 fw.writer.println("      Resource res = ListUtils.create(graph, "+ontShort+name+", Collections.EMPTY_LIST);");\r
215                 }\r
216                 fw.writer.println("      return res;");\r
217                 fw.writer.println("   }");\r
218                 fw.writer.println();\r
219                 \r
220                 fw.writer.println("   @Override");\r
221                 fw.writer.println("   public boolean connectParent(WriteGraph graph, Element parent, Element element) throws DatabaseException{");\r
222                 fw.writer.println("      "+getOntologyImport());\r
223                 fw.writer.println("      graph.claim(parent.getData(), "+this.ontShort+getName(complexTypeObj,"has")+", element.getData());");\r
224                 fw.writer.println("      return true;");\r
225                 fw.writer.println("   }");\r
226                 fw.writer.println();\r
227                                 \r
228                 StringWriter stringWriter = new StringWriter();\r
229                 fw.delayedWriter = new PrintWriter(stringWriter);\r
230                 StringWriter stringWriter2 = new StringWriter();\r
231                 fw.delayedWriter2 = new PrintWriter(stringWriter2);\r
232                 \r
233                 fw.writer.println("   public " + className + "() {");\r
234                 fw.writer.println("      super();");\r
235                 \r
236                 handleComplexTypeExtension(complexTypeObj);\r
237                 \r
238                 fw.writer.println("   }");\r
239                 \r
240                 fw.writer.println("   @Override");\r
241                 fw.writer.println("   public boolean connectChild(WriteGraph graph, Element element, Element child) throws DatabaseException{");\r
242                 fw.writer.println("      "+getOntologyImport());\r
243                 \r
244                 if (stringWriter.getBuffer().length() > 0) {\r
245                         fw.writer.write(stringWriter.toString());\r
246                 }\r
247                 \r
248                 \r
249                 fw.writer.println("      return false;");\r
250                 fw.writer.println("   }");\r
251                 fw.writer.println();\r
252                 \r
253                 if (stringWriter2.getBuffer().length() > 0) {\r
254                         fw.writer.write(stringWriter2.toString());\r
255                 }\r
256                 \r
257                 stringWriter = null;\r
258                 fw.delayedWriter.close();\r
259                 fw.delayedWriter=null;\r
260                 stringWriter2 = null;\r
261                 fw.delayedWriter2.close();\r
262                 fw.delayedWriter2 = null;\r
263                 \r
264                 fw.writer.println("   @Override");\r
265                 fw.writer.println("   public void configure(WriteGraph graph, Deque<Element> parents, Element element) throws DatabaseException {");\r
266                 if (inherited) {\r
267                 fw.writer.println("             super.configure(graph,parents,element);");\r
268                 }\r
269                 fw.writer.println("        "+getOntologyImport());\r
270                 \r
271                 handleComplexTypeAttributes(complexTypeObj);\r
272                 handleExtensionAttributes(complexTypeObj);\r
273                 \r
274                 fw.writer.println("   }");\r
275                 \r
276                 writeIDReferences(fw.writer,name, references);\r
277                 writeUnknownChild(fw.writer,name,unknownChildElement);\r
278                 \r
279                 fw.writer.println("}");\r
280                 fw.writer.println();\r
281                 fw.writer.flush();\r
282                 fw.writer.close();\r
283                 fw.writer = null;\r
284                 writers.remove(complexTypeObj);\r
285                 provider = null;\r
286         }\r
287         \r
288         @Override\r
289         protected void handle(SchemaObject parent, SchemaElement indicator, List<SchemaElement> elements) {\r
290                 if (indicator.getType() == SchemaElement.ElementType.SEQUENCE || (indicator.getType() == SchemaElement.ElementType.CHOICE && indicator.getRestriction().many())) {\r
291                         for (SchemaElement e : elements) {\r
292                                 handle(parent, indicator, e);\r
293                         }\r
294                 } else if (indicator.getType() == SchemaElement.ElementType.CHOICE) {\r
295                         String name = getChoiceName(elements);\r
296 \r
297                         for (SchemaElement e : elements) {\r
298                                 Element localElement = e.getElement();\r
299                                 if (localElement.getName() != null) {\r
300                                         QName refType = localElement.getType();\r
301                                         if (refType != null)\r
302                                                 handleIndicator(parent, indicator, e, false, name, refType);\r
303                                 } else if (localElement.getRef() != null) {\r
304                                         QName refType = localElement.getRef();\r
305                                         handleIndicator(parent, indicator, e, true, name, refType);\r
306                                 }\r
307                         }\r
308                 }\r
309                 \r
310         }\r
311         \r
312         @Override\r
313         protected void handleIndicator(SchemaObject parent, SchemaElement indicator, SchemaElement element,  boolean reference, String ref, QName refType) {\r
314                 FileWriter fw = getWriter(parent);\r
315                 String binding = getBindingFromPrimitiveType(refType);\r
316                 if (binding == null) {\r
317                         SchemaObject refElement = elementName.get(refType.getLocalPart());\r
318                         SchemaObject refComplexType = complexTypeName.get(refType.getLocalPart());\r
319 //                      String className = refType.getLocalPart();\r
320 //                      if (!isElementRef(refType.getLocalPart())) { \r
321 //                              className = "_"+className;\r
322 //                      }\r
323 //                      \r
324 //                      String refClassName = refType.getLocalPart();\r
325 //                      if (isComplexTypeRef(refClassName)) {\r
326 //                              refClassName = "_"+refClassName;\r
327 //                      }\r
328                         String className = null;\r
329                         String refClassName = null;\r
330                         if (refElement != null)\r
331                                 className = getName(refElement);\r
332                         else\r
333                                 className = getName(refComplexType);\r
334                         \r
335                         if (refComplexType != null) {\r
336                                 refClassName = getName(refComplexType);\r
337                         } else {\r
338                                 refClassName = getName(refElement);\r
339                         }\r
340                         \r
341                         if (!reference)\r
342                         fw.writer.println("        addParser(\""+ ref +"\", "+className+".class);");\r
343                         else\r
344                         fw.writer.println("        addParser("+className+".class);");\r
345                         if (!className.equals(refClassName))\r
346                         fw.writer.println("        addParser("+refClassName+".class);");\r
347                         \r
348                         fw.delayedWriter.println("         if (child.getParser() instanceof "+refClassName+"){");\r
349                         fw.delayedWriter.println("            graph.claim(element.getData(), "+ontShort+getName(parent)+"_has"+ref + ", child.getData());");\r
350                         if (useElementList(parent, indicator,element, reference, ref, refType)) {\r
351         \r
352                         // element type specific list\r
353                         fw.delayedWriter.println("            {");\r
354                         fw.delayedWriter.println("               Resource list = graph.getPossibleObject(element.getData(),"+ontShort+getName(parent)+"_has"+ref + "List);");\r
355                         fw.delayedWriter.println("               if (list == null) {");\r
356                         fw.delayedWriter.println("                  list = org.simantics.db.common.utils.ListUtils.create(graph, java.util.Collections.singletonList(child.getData()));");\r
357                         fw.delayedWriter.println("                  graph.claim(element.getData(),"+ontShort+getName(parent)+"_has"+ref + "List,list);");\r
358                         fw.delayedWriter.println("               } else {");\r
359                         fw.delayedWriter.println("                  org.simantics.db.common.utils.ListUtils.insertBack(graph, list, java.util.Collections.singletonList(child.getData()));");\r
360                         fw.delayedWriter.println("               }");\r
361                         fw.delayedWriter.println("            }");\r
362                         }\r
363                         if (useOriginalList(parent, indicator,element, reference, ref, refType)) {\r
364                         // generic list\r
365                         fw.delayedWriter.println("            {");\r
366                         fw.delayedWriter.println("               Resource list = graph.getPossibleObject(element.getData(),"+ontShort+"XML_hasOriginalElementList);");\r
367                         fw.delayedWriter.println("               if (list == null) {");\r
368                         fw.delayedWriter.println("                  list = org.simantics.db.common.utils.ListUtils.create(graph, java.util.Collections.singletonList(child.getData()));");\r
369                         fw.delayedWriter.println("                  graph.claim(element.getData(),"+ontShort+"XML_hasOriginalElementList,list);");\r
370                         fw.delayedWriter.println("               } else {");\r
371                         fw.delayedWriter.println("                  org.simantics.db.common.utils.ListUtils.insertBack(graph, list, java.util.Collections.singletonList(child.getData()));");\r
372                         fw.delayedWriter.println("               }");\r
373                         fw.delayedWriter.println("            }");\r
374                         }\r
375                         \r
376                         fw.delayedWriter.println("            return true;");\r
377                         fw.delayedWriter.println("         }");\r
378                 } else {\r
379                         //writer.println(commentTag+ontShort+"."+parent+".has"+ref + " <R " +  ontShort+".hasElement");\r
380                         fw.writer.println("        addParser(\""+ ref +"\", "+getName(parent) +"_" +ref+".class);");\r
381                         \r
382                         fw.delayedWriter2.println("   public static class " + getName(parent) +"_" +ref+" extends org.simantics.xml.sax.base.ValueElementParser {");\r
383                         fw.delayedWriter2.println("      "+ getName(parent) +"_" +ref +"(){");\r
384                         fw.delayedWriter2.println("           super(\""+ref+"\"," +this.ontologyClassName+".URIs."+getName(parent) + "_has"+ref+", Bindings."+binding+");");\r
385                         fw.delayedWriter2.println("       }");\r
386                         fw.delayedWriter2.println("   }");\r
387                 }\r
388         }\r
389         \r
390         @Override\r
391         protected void handleIndicator(SchemaObject parent, SchemaElement indicator, SchemaElement element,  boolean reference, String ref, OpenAttrs attrs) {\r
392                 FileWriter fw = getWriter(parent);\r
393                 SchemaObject obj = getWithObj(parent, attrs);\r
394         \r
395 //              String className = refType.getLocalPart();\r
396 //              if (!isElementRef(refType.getLocalPart())) { \r
397 //                      className = "_"+className;\r
398 //              }\r
399 //              \r
400 //              String refClassName = refType.getLocalPart();\r
401 //              if (isComplexTypeRef(refClassName)) {\r
402 //                      refClassName = "_"+refClassName;\r
403 //              }\r
404                 String className = getName(obj);\r
405                 \r
406                 \r
407                 if (!reference)\r
408                 fw.writer.println("        addParser(\""+ ref +"\", "+className+".class);");\r
409                 else\r
410                 fw.writer.println("        addParser("+className+".class);");\r
411                 \r
412                 fw.delayedWriter.println("         if (child.getParser() instanceof "+className+"){");\r
413                 fw.delayedWriter.println("            graph.claim(element.getData(), "+ontShort+getName(parent)+"_has"+ref + ", child.getData());");\r
414                 if (useElementList(parent, indicator,element, reference, ref, new QName(obj.getName()))) {\r
415 \r
416                 // element type specific list\r
417                 fw.delayedWriter.println("            {");\r
418                 fw.delayedWriter.println("               Resource list = graph.getPossibleObject(element.getData(),"+ontShort+getName(parent)+"_has"+ref + "List);");\r
419                 fw.delayedWriter.println("               if (list == null) {");\r
420                 fw.delayedWriter.println("                  list = org.simantics.db.common.utils.ListUtils.create(graph, java.util.Collections.singletonList(child.getData()));");\r
421                 fw.delayedWriter.println("                  graph.claim(element.getData(),"+ontShort+getName(parent)+"_has"+ref + "List,list);");\r
422                 fw.delayedWriter.println("               } else {");\r
423                 fw.delayedWriter.println("                  org.simantics.db.common.utils.ListUtils.insertBack(graph, list, java.util.Collections.singletonList(child.getData()));");\r
424                 fw.delayedWriter.println("               }");\r
425                 fw.delayedWriter.println("            }");\r
426                 }\r
427                 if (useOriginalList(parent, indicator,element, reference, ref, new QName(obj.getName()))) {\r
428                 // generic list\r
429                 fw.delayedWriter.println("            {");\r
430                 fw.delayedWriter.println("               Resource list = graph.getPossibleObject(element.getData(),"+ontShort+"XML_hasOriginalElementList);");\r
431                 fw.delayedWriter.println("               if (list == null) {");\r
432                 fw.delayedWriter.println("                  list = org.simantics.db.common.utils.ListUtils.create(graph, java.util.Collections.singletonList(child.getData()));");\r
433                 fw.delayedWriter.println("                  graph.claim(element.getData(),"+ontShort+"XML_hasOriginalElementList,list);");\r
434                 fw.delayedWriter.println("               } else {");\r
435                 fw.delayedWriter.println("                  org.simantics.db.common.utils.ListUtils.insertBack(graph, list, java.util.Collections.singletonList(child.getData()));");\r
436                 fw.delayedWriter.println("               }");\r
437                 fw.delayedWriter.println("            }");\r
438                 }\r
439                 \r
440                 fw.delayedWriter.println("            return true;");\r
441                 fw.delayedWriter.println("         }");\r
442                 \r
443         }\r
444         \r
445         @Override\r
446         protected void handleIndicator(SchemaObject parent, SchemaElement indicator, SchemaElement any) {               \r
447                 FileWriter fw = getWriter(parent);\r
448                 fw.delayedWriter2.println("   @Override");\r
449                 fw.delayedWriter2.println("   public Class<? extends org.simantics.xml.sax.base.XMLElementParser> getParser(java.util.Map<java.lang.String,org.simantics.xml.sax.base.XMLElementParser> parsers, Element element, Element child) {");\r
450                 fw.delayedWriter2.println("      Class<? extends org.simantics.xml.sax.base.XMLElementParser> parserClass = super.getParser(parsers, element, child);");\r
451                 fw.delayedWriter2.println("      if (parserClass != null) return parserClass;");\r
452                 fw.delayedWriter2.println("      org.simantics.xml.sax.base.XMLElementParser parser = parsers.get(child.getQName());");\r
453                 fw.delayedWriter2.println("      if (parser != null) return parser.getClass();");\r
454                 fw.delayedWriter2.println("      return null;");\r
455                 fw.delayedWriter2.println("   }");\r
456         }\r
457         \r
458         private FileWriter getWriter(SchemaObject obj) {\r
459                 SchemaObject s = obj;\r
460                 while (s != null) {\r
461                         FileWriter fw = writers.get(s);\r
462                         if (fw != null)\r
463                                 return fw;\r
464                         s = s.getParent();\r
465                 }\r
466                 return null;\r
467         }\r
468         \r
469         \r
470         @Override       \r
471         protected void handle(SchemaObject parent, Attribute attribute) {\r
472                 String name = attribute.getName();\r
473                 QName primitiveType = attribute.getType();\r
474                 SimpleType simpleType = attribute.getSimpleType();\r
475                 QName ref = attribute.getRef();\r
476                 \r
477                 String relationName;\r
478                 String attrName;\r
479                 if (name != null) {\r
480                         attrName = name;\r
481                         relationName = ontShort+"has"+name;\r
482                         if (parent != null)\r
483                                 relationName = ontShort+getName(parent)+"_has"+name;\r
484                 }\r
485                 else if (ref != null && parent != null) {\r
486                         attrName = ref.getLocalPart();\r
487                         relationName = ontShort+getName(parent)+"_has"+ref.getLocalPart();\r
488                         \r
489                         Attribute referred = getRefAttribute(ref);\r
490                         if (referred != null) {\r
491                                 primitiveType = referred.getType();\r
492                                 simpleType = referred.getSimpleType();\r
493                         }\r
494                         \r
495                 } else {\r
496                         throw new RuntimeException();\r
497                 }\r
498                 boolean isReference = false;\r
499                 if (provider!= null && provider.getAttribute().getName().equals(attrName))\r
500                         isReference = true;\r
501                 \r
502                 FileWriter fw = getWriter(parent);\r
503                 if (primitiveType != null) {\r
504                         \r
505                         String binding = getBindingFromPrimitiveType(primitiveType);\r
506                         \r
507                         if (binding != null) {\r
508                                 writeAttribute(fw, attrName, relationName, binding, isReference);\r
509                                 return;\r
510                     } else {\r
511                         if (simpleType == null) {\r
512                                 SchemaObject simpleTypeObj = simpleTypeName.get(primitiveType.getLocalPart());\r
513                                 if (simpleTypeObj != null)\r
514                                         simpleType = simpleTypeObj.getSimpleType();\r
515                         }       \r
516                     }\r
517                 } \r
518                 if (simpleType != null) {\r
519                         Restriction restriction = simpleType.getRestriction();\r
520                         if (restriction == null)\r
521                                 throw new RuntimeException("Cannot resolve type for Attribute " + attrName + " -> " + primitiveType.getLocalPart()+ ", SimpleType restriction is unset");\r
522                         QName base = restriction.getBase();\r
523                         \r
524                         \r
525                         String binding = getBindingFromPrimitiveType(base);\r
526                         writeAttribute(fw, attrName, relationName, binding, isReference);\r
527                 } else {\r
528                         //throw new RuntimeException("Cannot resolve type for Attribute " + attrName + " -> " + primitiveType.getLocalPart());\r
529                         //writeAttribute(fw, attrName, relationName, binding, isReference);\r
530                 }\r
531         }\r
532         \r
533         private void writeAttribute(FileWriter fw, String attrName, String relationName, String binding, boolean isReference) {\r
534                 fw.writer.println("      {");\r
535                 fw.writer.println("         Attribute a = element.getAttribute(\"" +attrName+"\");");\r
536                 fw.writer.println("         if (a != null) {");\r
537                 fw.writer.println("            graph.claimLiteral(element.getData(),"+relationName+","+getValueGetter(binding,"a")+", Bindings."+binding+");");\r
538                 if (isReference)\r
539                 fw.writer.println("            idProviderValue = a.getValue();");       \r
540                 fw.writer.println("         }");\r
541                 fw.writer.println("      }");\r
542         }\r
543         \r
544         @Override\r
545         protected void handleAttributes(SchemaObject simpleTypeObj) {\r
546                 SchemaObject parent = simpleTypeObj.getParent();\r
547                 FileWriter fw = getWriter(parent);\r
548                 \r
549                 SimpleType simpleType = simpleTypeObj.getSimpleType();\r
550                 Restriction restriction = simpleType.getRestriction();\r
551                 if (restriction == null)\r
552                         throw new RuntimeException("Cannot resolve type for Element " + getName(parent));\r
553                 QName base = restriction.getBase();\r
554                 \r
555                 \r
556                 String binding = getBindingFromPrimitiveType(base);\r
557                 fw.writer.println("   @Override");\r
558                 fw.writer.println("   public void configure(WriteGraph graph, Element element, java.lang.String value) throws DatabaseException {");\r
559                 fw.writer.println("      graph.claimValue(element.getData(),"+getValueGetter(binding)+", Bindings."+binding+");");\r
560                 fw.writer.println("   }");\r
561                 \r
562         }\r
563         \r
564         @Override\r
565         protected void handle(SchemaObject parent, AttributeGroup attribute) {\r
566                 if (parent != null) {\r
567                         FileWriter fw = getWriter(parent);\r
568                         NamedAttributeGroup group = getAttributeGroup(attribute.getRef().getLocalPart());\r
569                         fw.writer.println(commentTag+"    AttributeGroup " + group.getName());\r
570                         SchemaObject obj = new SchemaObject(parent,attribute);\r
571                         for (Annotated annotated : group.getAttributeOrAttributeGroup()) {\r
572                                 if (annotated instanceof Attribute) {\r
573                                         //handle("AttributeGroups_"+group.getName(),(Attribute)annotated);\r
574                                         handle(obj,(Attribute)annotated);\r
575                                 } else if (annotated instanceof AttributeGroup) {\r
576                                         //handle("AttributeGroups_"+group.getName(),(AttributeGroup)annotated);\r
577                                         handle(obj,(AttributeGroup)annotated);\r
578                                 }\r
579                         }\r
580                         fw.writer.println(commentTag+"    End of AttributeGroup " + group.getName());\r
581                 }\r
582                 \r
583         }\r
584         \r
585         @Override\r
586         protected void handleAttributeComposition(SchemaObject parent, AttributeComposition composition, BijectionMap<org.simantics.xml.sax.configuration.Attribute, Annotated> attributes) {\r
587                 FileWriter fw = getWriter(parent);\r
588                 QName type = new QName(CONVERSION_NS, composition.getType());\r
589                 String arrayBinding = getBindingFromPrimitiveType(type);\r
590                 String javaType = getJavaTypeFromPrimitiveType(type);\r
591                 String name = composition.getName();\r
592                 \r
593                 String relationName;\r
594                 if (name != null) {\r
595                         relationName = ontShort+"has"+name;\r
596                         if (parent != null)\r
597                                 relationName = ontShort+getName(parent)+"_has"+name;\r
598                 } else {\r
599                         throw new RuntimeException();\r
600                 }\r
601                 \r
602                 fw.writer.println("      {");\r
603                 int i = 0;\r
604                 for (org.simantics.xml.sax.configuration.Attribute a : composition.getAttribute())\r
605                 fw.writer.println("         Attribute a"+(i++)+" = element.getAttribute(\"" +a.getName()+"\");");\r
606                 fw.writer.print  ("         "+javaType + " value = new "+javaType+"{");\r
607                 i = 0;\r
608                 // FIXME : handle optional attributes properly.\r
609                 for (org.simantics.xml.sax.configuration.Attribute a : composition.getAttribute()) {\r
610                         Attribute attribute = ((Attribute)attributes.getRight(a));\r
611                         //QName atype = getBaseType(attribute);\r
612                         QName atype = getPrimitiveType(attribute);\r
613                         String defaultValue = attribute.getDefault();\r
614                         if (defaultValue == null)\r
615                             defaultValue = getDefaultValue(atype);\r
616                                 \r
617                         String binding = getBindingFromPrimitiveType(atype);\r
618                         if (i > 0)\r
619                                 fw.writer.print(",");\r
620                         if (defaultValue != null)\r
621                                 fw.writer.print("a"+(i)+"!= null ? "+ getValueGetter(binding,"a"+(i++)) + " : " +defaultValue);\r
622                         else\r
623                                 fw.writer.print(getValueGetter(binding,"a"+(i++)));\r
624                 }\r
625                 fw.writer.println("};");\r
626                 fw.writer.println("         graph.claimLiteral(element.getData(),"+relationName+", value, Bindings."+arrayBinding+");");\r
627                 fw.writer.println("      }");\r
628                 \r
629         }\r
630         \r
631         protected String getDefaultValue(QName atype) {\r
632                 Map<String,TypeEntry> types = typeMap.get(atype.getNamespaceURI());\r
633                 if (types == null)\r
634                         return null;\r
635                 TypeEntry entry =  types.get(atype.getLocalPart());\r
636                 if (entry == null)\r
637                         return null;\r
638                 return entry.defaultValue;\r
639         }\r
640         \r
641         \r
642         @Override\r
643         protected void handleSimpleType(SchemaObject parent, SchemaObject simpleType) {\r
644 \r
645         }\r
646         \r
647         \r
648         \r
649         IDProvider provider;\r
650         @Override\r
651         protected void handleElement(SchemaObject elementObj)  {\r
652                 Element element = elementObj.getElement();\r
653                 \r
654                 String name = getName(elementObj);//topLevelElement.getName();\r
655                 String className = name;\r
656                 \r
657                 FileWriter fw = new FileWriter();\r
658                 try {\r
659                         fw.writer = createFile(new File(importParserDir.getAbsolutePath()+"/"+className+".java"));\r
660                 } catch (IOException e) {\r
661                         throw new RuntimeException(e);\r
662                 }\r
663                 writers.put(elementObj, fw);\r
664                 boolean isList = false;\r
665                 \r
666                 Pair<String, Boolean> inhertiance = getElementInheritance(elementObj);\r
667                 boolean inherited = inhertiance.second;\r
668                 String baseClass = inhertiance.first;//"org.simantics.xml.sax.base.XMLElementParserBase";\r
669                 \r
670                 \r
671                 provider = getIDProvider(element);\r
672                 List<IDReference> references = getIDReferences(element);\r
673                 UnrecognizedChildElement unknownChildElement = getUnknown(element);\r
674 \r
675                 List<String> intrerfaces = new ArrayList<String>();\r
676                 if (references.size() > 0)\r
677                         intrerfaces.add("org.simantics.xml.sax.base.IDReferenceParser");\r
678                 if (unknownChildElement != null)\r
679                         intrerfaces.add("org.simantics.xml.sax.base.UnrecognizedElementParser");\r
680 \r
681                 createClassHeader(fw.writer, isList);\r
682                 writeClass(fw.writer,false, element.getName(), className, baseClass, intrerfaces);\r
683                 writeIDProvider(fw.writer);\r
684                 fw.writer.println("   @Override");\r
685                 fw.writer.println("   public Resource create(WriteGraph graph, Element element) throws DatabaseException{");\r
686                 fw.writer.println("      Layer0 L0 = Layer0.getInstance(graph);");\r
687                 fw.writer.println("      "+getOntologyImport());\r
688                 if (!isList) {\r
689                 fw.writer.println("      Resource res = graph.newResource();");\r
690                 fw.writer.println("      graph.claim(res, L0.InstanceOf, "+ontShort+name+");");\r
691                 } else {\r
692                 fw.writer.println("      Resource res = ListUtils.create(graph, "+ontShort+name+", Collections.EMPTY_LIST);");\r
693                 }\r
694                 fw.writer.println("      return res;");\r
695                 fw.writer.println("   }");\r
696                 fw.writer.println();\r
697                 \r
698                 fw.writer.println("   @Override");\r
699                 fw.writer.println("   public boolean connectParent(WriteGraph graph, Element parent, Element element) throws DatabaseException{");\r
700                 fw.writer.println("      "+getOntologyImport());\r
701                 fw.writer.println("      graph.claim(parent.getData(), "+this.ontShort+getName(elementObj,"has")+", element.getData());");\r
702                 fw.writer.println("      return true;");\r
703                 fw.writer.println("   }");\r
704                 fw.writer.println();\r
705                 \r
706                 fw.writer.println("   @Override");\r
707                 fw.writer.println("   public void configure(WriteGraph graph, Deque<Element> parents, Element element) throws DatabaseException {");\r
708                 if (inherited) {\r
709                 fw.writer.println("             super.configure(graph,parents,element);");\r
710                 }\r
711                 fw.writer.println("        "+getOntologyImport());\r
712                 \r
713                 LocalComplexType complexType = element.getComplexType();\r
714                 LocalSimpleType simpleType = element.getSimpleType();\r
715                 \r
716                 if (complexType != null) {\r
717                         SchemaObject obj = complexTypes.get(complexType);\r
718                         handleElementComplexTypeAttributes(obj);\r
719                 } \r
720                 fw.writer.println("   }");\r
721                 \r
722                 if (simpleType != null) {\r
723                         SchemaObject obj = simpleTypes.get(simpleType);\r
724                         handleElementSimpleTypeAttributes(obj);\r
725                 }\r
726                 \r
727                 \r
728                 StringWriter stringWriter = new StringWriter();\r
729                 fw.delayedWriter = new PrintWriter(stringWriter);\r
730                 StringWriter stringWriter2 = new StringWriter();\r
731                 fw.delayedWriter2 = new PrintWriter(stringWriter2);\r
732                 \r
733                 fw.writer.println("   public " + className + "() {");\r
734                 fw.writer.println("      super();");\r
735                 \r
736                 if (complexType != null) {\r
737                         SchemaObject obj = complexTypes.get(complexType);\r
738                         handleComplexTypeExtension(obj);\r
739                 } else if (simpleType != null) {\r
740                         \r
741                 }\r
742                 \r
743                 fw.writer.println("   }");\r
744                 \r
745                 fw.writer.println("   @Override");\r
746                 fw.writer.println("   public boolean connectChild(WriteGraph graph, Element element, Element child) throws DatabaseException{");\r
747                 fw.writer.println("      "+getOntologyImport());\r
748                 \r
749                 if (stringWriter.getBuffer().length() > 0) {\r
750                         fw.writer.write(stringWriter.toString());\r
751                 }\r
752                 if (inherited) {\r
753                 fw.writer.println("      return super.connectChild(graph,element,child);");     \r
754                 } else {\r
755                 fw.writer.println("      return false;");\r
756                 }\r
757                 fw.writer.println("   }");\r
758                 fw.writer.println();\r
759                 \r
760                 if (stringWriter2.getBuffer().length() > 0) {\r
761                         fw.writer.write(stringWriter2.toString());\r
762                 }\r
763                 \r
764                 stringWriter = null;\r
765                 fw.delayedWriter.close();\r
766                 fw.delayedWriter = null;\r
767                 stringWriter2 = null;\r
768                 fw.delayedWriter2.close();\r
769                 fw.delayedWriter2 = null;\r
770                 \r
771                 writeIDReferences(fw.writer,name, references);\r
772                 writeUnknownChild(fw.writer,name,unknownChildElement);\r
773 \r
774                 fw.writer.println("}");\r
775                 fw.writer.println();\r
776                 fw.writer.flush();\r
777                 fw.writer.close();\r
778                 fw.writer = null;\r
779                 writers.remove(elementObj);\r
780                 provider = null;\r
781                 \r
782                 ruleClassNames.add(converter.getPluginName()+"."+elementPackageName+"."+name);\r
783         }\r
784         \r
785         private Pair<String,Boolean> getElementInheritance(SchemaObject topLevelElementObj) {\r
786                 Element topLevelElement = topLevelElementObj.getElement();\r
787                 String baseClass = "org.simantics.xml.sax.base.XMLElementNamedChildParserBase";\r
788                 boolean inherited = false;\r
789                 if (topLevelElement.getType() != null) {\r
790                         QName type = topLevelElement.getType();\r
791                         if (!type.getNamespaceURI().equals(SCHEMA_NS)) {\r
792                                 SchemaObject obj = complexTypeName.get(type.getLocalPart());\r
793                                 baseClass = getName(obj);\r
794                                 inherited = true;\r
795                         }       \r
796                 }\r
797                 if (!inherited) {\r
798                         QName type = getElementBase(topLevelElement);\r
799                         if (type != null) {\r
800                                 if (!type.getNamespaceURI().equals(SCHEMA_NS)) {\r
801                                         SchemaObject obj = getWithName(topLevelElementObj, type.getLocalPart());\r
802                                         baseClass = getName(obj);\r
803                                         inherited = true;\r
804                                 }       \r
805                         }\r
806                 }\r
807                 if (!inherited) {\r
808                         QName type = topLevelElement.getSubstitutionGroup();\r
809                         if (type != null) {\r
810                                 if (!type.getNamespaceURI().equals(SCHEMA_NS)) {\r
811                                         SchemaObject obj = getWithName(topLevelElementObj, type.getLocalPart());\r
812                                         baseClass = getName(obj);\r
813                                         inherited = true;\r
814                                 }       \r
815                         }\r
816                 }\r
817                 \r
818                 return new Pair<String, Boolean>(baseClass, inherited);\r
819         }\r
820         \r
821         private void writeClass(PrintWriter writer,boolean abst, String name, String className, String baseClass, List<String> interfaces) {\r
822                 writer.println("@SuppressWarnings(\"unused\")");\r
823                 writer.print("public " +(abst ? "abstract " : "") + "class " + className + " extends "+baseClass);\r
824                 if (interfaces.size() > 0) {\r
825                         writer.print(" implements ");\r
826                         for (int i = 0; i < interfaces.size(); i++) {\r
827                                 writer.print(interfaces.get(i));\r
828                                 if (i < interfaces.size() -1 )\r
829                                         writer.print(",");\r
830                         }\r
831                 }\r
832                 writer.println("{");\r
833                 writer.println();\r
834                 writer.println("   @Override");\r
835                 writer.println("   public java.lang.String getElementId() {");\r
836                 if (name != null)\r
837                 writer.println("      return \""+name+"\";");\r
838                 else // complex types cannot be parsed directly with name/id reference.\r
839                 writer.println("      return null;");\r
840                 writer.println("   }");\r
841                 writer.println();\r
842         }\r
843         \r
844         private void writeIDProvider(PrintWriter writer) {\r
845                 if (provider != null) {\r
846                 writer.println("   java.lang.String idProviderValue = null;");\r
847                 writer.println();\r
848                 writer.println("   @Override");\r
849                 writer.println("   public java.lang.String getID() {");\r
850                 writer.println("        java.lang.String s = idProviderValue;");\r
851                 writer.println("        idProviderValue = null;");\r
852                 writer.println("        return s;");\r
853                 writer.println("   }");\r
854                 writer.println();\r
855                 if (provider.getPriority() != null) {\r
856                 writer.println("   @Override");\r
857                 writer.println("   public int idPriority() {");\r
858                 writer.println("        return " + provider.getPriority().intValue()+";");\r
859                 writer.println("   }"); \r
860                 }\r
861                 }\r
862         }\r
863         \r
864         private void writeIDReferences(PrintWriter writer,String name, List<IDReference> references) {\r
865                 if (references.size() > 0) {\r
866                 writer.println("   @Override");\r
867                 writer.println("   public boolean connectReferences(WriteGraph graph, Element element, java.util.Map<java.lang.String, Element> map) throws DatabaseException {");\r
868                 writer.println("      "+getOntologyImport());\r
869                 writer.println("      boolean result = true;");\r
870                 for (IDReference ref : references) {\r
871                 writer.println("      {");\r
872                 writer.println("         Attribute a = element.getAttribute(\"" + ref.getIDSource().getName() +"\");");\r
873                 writer.println("         if (a != null) {");\r
874                 writer.println("            Element refEle = map.get(a.value);");\r
875                 writer.println("            if (refEle != null) {");\r
876                 writer.println("               Resource ref = refEle.getData();");\r
877                 writer.println("               graph.claim(element.getData(), "+ontShort+name+"_"+ref.getReference().getName()+", ref);");\r
878                 writer.println("            } else {");\r
879                 writer.println("               result = false;");\r
880                 writer.println("            }");\r
881                 writer.println("         }");\r
882                 writer.println("      }");\r
883                 }\r
884                 writer.println("      return result;");\r
885                 writer.println("   }");\r
886                 writer.println();\r
887                 }\r
888         }\r
889         \r
890         private void writeUnknownChild(PrintWriter writer,String name, UnrecognizedChildElement unknownChildElement) {\r
891                 if (unknownChildElement == null)\r
892                         return;\r
893                 \r
894                 writer.println("   @Override");\r
895                 writer.println("   public void configureChild(WriteGraph graph, Deque<Element> parents, Element element, Element child) throws DatabaseException {");\r
896                 writer.println("    " + unknownChildElement.getJavaMethod());\r
897                 writer.println("   }");\r
898                 writer.println();\r
899                 \r
900         }\r
901         \r
902         protected void createClassHeader(PrintWriter writer, boolean isList) {\r
903                 writer.println("package " + converter.getPluginName() +"."+elementPackageName+";");\r
904                 writer.println();\r
905                 writer.println("import java.util.Deque;");\r
906                 writer.println("import org.simantics.databoard.Bindings;");\r
907                 writer.println("import org.simantics.db.Resource;");\r
908                 writer.println("import org.simantics.db.WriteGraph;");\r
909                 writer.println("import org.simantics.db.exception.DatabaseException;");\r
910                 writer.println("import org.simantics.xml.sax.base.Attribute;");\r
911                 writer.println("import org.simantics.xml.sax.base.Element;");\r
912                 if (!isList) {\r
913                 writer.println("import org.simantics.layer0.Layer0;");\r
914             } else {\r
915             writer.println("import java.util.Collections;");\r
916                 writer.println("import org.simantics.db.common.utils.ListUtils;");\r
917                 }\r
918                 writer.println();\r
919         }\r
920         \r
921         private String getOntologyImport() {\r
922                 return this.ontologyClassName+" " +ontShort.substring(0, 3)+" = "+this.ontologyClassName+".getInstance(graph);";\r
923         }\r
924         \r
925         \r
926         private static class FileWriter {\r
927                 public PrintWriter writer;\r
928                 \r
929                 public PrintWriter delayedWriter;\r
930                 public PrintWriter delayedWriter2;\r
931         }\r
932         \r
933         public static String getName(SchemaObject obj) {\r
934                 if (obj.getParent() == null) {\r
935                         switch (obj.getType()) {\r
936                         case COMPLEX_TYPE:\r
937                                 return getComplexTypePrefix()+obj.getName();\r
938                         case ELEMENT:\r
939                                 return obj.getName();\r
940                         case ATTRIBUTE_GROUP:\r
941                                 return getAttributeGroupPrefix()+obj.getName();\r
942                         case SIMPLE_TYPE:\r
943                                 return obj.getName();\r
944                         }\r
945                 } else {\r
946                         SchemaObject o = obj;\r
947                         SchemaObject prev = null;\r
948                         String name = "";\r
949                         while (o != null){\r
950                                 if (o.getName() != null)\r
951                                         name = o.getName()+"_"+name;\r
952                                 prev = o;\r
953                                 o = o.getParent();\r
954                                 if (prev.getObj() instanceof AttributeGroupRef)\r
955                                         o = null;\r
956                         }\r
957                         name = name.substring(0, name.length()-1);\r
958                         switch (prev.getType()) {\r
959                         case COMPLEX_TYPE:\r
960                                 return getComplexTypePrefix()+name;\r
961                         case ELEMENT:\r
962                                 return name;\r
963                         case ATTRIBUTE_GROUP:\r
964                                 return getAttributeGroupPrefix()+name;\r
965                         case SIMPLE_TYPE:\r
966                                 return name;\r
967                         }\r
968                 }\r
969                 throw new RuntimeException();\r
970                 \r
971         }\r
972         \r
973         public static String getName(SchemaObject obj, String rel) {\r
974                 if (obj.getParent() == null) {\r
975                         switch (obj.getType()) {\r
976                         case COMPLEX_TYPE:\r
977                                 return getComplexTypePrefix()+rel+obj.getName();\r
978                         case ELEMENT:\r
979                                 return rel+obj.getName();\r
980                         case ATTRIBUTE_GROUP:\r
981                                 return getAttributeGroupPrefix()+rel+obj.getName();\r
982                         case SIMPLE_TYPE:\r
983                                 return rel+obj.getName();\r
984                         }\r
985                 } else {\r
986                         SchemaObject o = obj;\r
987                         SchemaObject prev = null;\r
988                         String name = "";\r
989                         while (o != null){\r
990                                 if (o.getName() != null)\r
991                                         name = o.getName()+"_"+name;\r
992                                 prev = o;\r
993                                 o = o.getParent();\r
994                         }\r
995                         name = name.substring(0, name.length()-1);\r
996                         switch (prev.getType()) {\r
997                         case COMPLEX_TYPE:\r
998                                 return getComplexTypePrefix()+rel+name;\r
999                         case ELEMENT:\r
1000                                 return rel+name;\r
1001                         case ATTRIBUTE_GROUP:\r
1002                                 return getAttributeGroupPrefix()+rel+name;\r
1003                         case SIMPLE_TYPE:\r
1004                                 return rel+name;\r
1005                         }\r
1006                 }\r
1007                 throw new RuntimeException();\r
1008                 \r
1009         }\r
1010 }\r