]> gerrit.simantics Code Review - simantics/interop.git/blob - org.simantics.xml.sax/src/org/simantics/xml/sax/ImporterGenerator.java
cff87ed72fcfc43ef3b65ac1d5090eadf687c287
[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                 }\r
530         }\r
531         \r
532         private void writeAttribute(FileWriter fw, String attrName, String relationName, String binding, boolean isReference) {\r
533                 fw.writer.println("      {");\r
534                 fw.writer.println("         Attribute a = element.getAttribute(\"" +attrName+"\");");\r
535                 fw.writer.println("         if (a != null) {");\r
536                 fw.writer.println("            graph.claimLiteral(element.getData(),"+relationName+","+getValueGetter(binding,"a")+", Bindings."+binding+");");\r
537                 if (isReference)\r
538                 fw.writer.println("            idProviderValue = a.getValue();");       \r
539                 fw.writer.println("         }");\r
540                 fw.writer.println("      }");\r
541         }\r
542         \r
543         @Override\r
544         protected void handleAttributes(SchemaObject simpleTypeObj) {\r
545                 SchemaObject parent = simpleTypeObj.getParent();\r
546                 FileWriter fw = getWriter(parent);\r
547                 \r
548                 SimpleType simpleType = simpleTypeObj.getSimpleType();\r
549                 Restriction restriction = simpleType.getRestriction();\r
550                 if (restriction == null)\r
551                         throw new RuntimeException("Cannot resolve type for Element " + getName(parent));\r
552                 QName base = restriction.getBase();\r
553                 \r
554                 \r
555                 String binding = getBindingFromPrimitiveType(base);\r
556                 fw.writer.println("   @Override");\r
557                 fw.writer.println("   public void configure(WriteGraph graph, Element element, java.lang.String value) throws DatabaseException {");\r
558                 fw.writer.println("      graph.claimValue(element.getData(),"+getValueGetter(binding)+", Bindings."+binding+");");\r
559                 fw.writer.println("   }");\r
560                 \r
561         }\r
562         \r
563         @Override\r
564         protected void handle(SchemaObject parent, AttributeGroup attribute) {\r
565                 if (parent != null) {\r
566                         FileWriter fw = getWriter(parent);\r
567                         NamedAttributeGroup group = getAttributeGroup(attribute.getRef().getLocalPart());\r
568                         fw.writer.println(commentTag+"    AttributeGroup " + group.getName());\r
569                         SchemaObject obj = new SchemaObject(parent,attribute);\r
570                         for (Annotated annotated : group.getAttributeOrAttributeGroup()) {\r
571                                 if (annotated instanceof Attribute) {\r
572                                         //handle("AttributeGroups_"+group.getName(),(Attribute)annotated);\r
573                                         handle(obj,(Attribute)annotated);\r
574                                 } else if (annotated instanceof AttributeGroup) {\r
575                                         //handle("AttributeGroups_"+group.getName(),(AttributeGroup)annotated);\r
576                                         handle(obj,(AttributeGroup)annotated);\r
577                                 }\r
578                         }\r
579                         fw.writer.println(commentTag+"    End of AttributeGroup " + group.getName());\r
580                 }\r
581                 \r
582         }\r
583         \r
584         @Override\r
585         protected void handleAttributeComposition(SchemaObject parent, AttributeComposition composition, BijectionMap<org.simantics.xml.sax.configuration.Attribute, Annotated> attributes) {\r
586                 FileWriter fw = getWriter(parent);\r
587                 QName type = new QName(CONVERSION_NS, composition.getType());\r
588                 String arrayBinding = getBindingFromPrimitiveType(type);\r
589                 String javaType = getJavaTypeFromPrimitiveType(type);\r
590                 String name = composition.getName();\r
591                 \r
592                 String relationName;\r
593                 if (name != null) {\r
594                         relationName = ontShort+"has"+name;\r
595                         if (parent != null)\r
596                                 relationName = ontShort+getName(parent)+"_has"+name;\r
597                 } else {\r
598                         throw new RuntimeException();\r
599                 }\r
600                 \r
601                 fw.writer.println("      {");\r
602                 int i = 0;\r
603                 for (org.simantics.xml.sax.configuration.Attribute a : composition.getAttribute())\r
604                 fw.writer.println("         Attribute a"+(i++)+" = element.getAttribute(\"" +a.getName()+"\");");\r
605                 fw.writer.print  ("         "+javaType + " value = new "+javaType+"{");\r
606                 i = 0;\r
607                 // FIXME : handle optional attributes properly.\r
608                 for (org.simantics.xml.sax.configuration.Attribute a : composition.getAttribute()) {\r
609                         Attribute attribute = ((Attribute)attributes.getRight(a));\r
610                         QName atype = getBaseType(attribute);\r
611                         String defaultValue = attribute.getDefault();\r
612                         if (defaultValue == null)\r
613                             defaultValue = getDefaultValue(atype);\r
614                                 \r
615                         String binding = getBindingFromPrimitiveType(atype);\r
616                         if (i > 0)\r
617                                 fw.writer.print(",");\r
618                         if (defaultValue != null)\r
619                                 fw.writer.print("a"+(i)+"!= null ? "+ getValueGetter(binding,"a"+(i++)) + " : " +defaultValue);\r
620                         else\r
621                                 fw.writer.print(getValueGetter(binding,"a"+(i++)));\r
622                 }\r
623                 fw.writer.println("};");\r
624                 fw.writer.println("         graph.claimLiteral(element.getData(),"+relationName+", value, Bindings."+arrayBinding+");");\r
625                 fw.writer.println("      }");\r
626                 \r
627         }\r
628         \r
629         protected String getDefaultValue(QName atype) {\r
630                 Map<String,TypeEntry> types = typeMap.get(atype.getNamespaceURI());\r
631                 if (types == null)\r
632                         return null;\r
633                 TypeEntry entry =  types.get(atype.getLocalPart());\r
634                 if (entry == null)\r
635                         return null;\r
636                 return entry.defaultValue;\r
637         }\r
638         \r
639         \r
640         @Override\r
641         protected void handleSimpleType(SchemaObject parent, SchemaObject simpleType) {\r
642 \r
643         }\r
644         \r
645         \r
646         \r
647         IDProvider provider;\r
648         @Override\r
649         protected void handleElement(SchemaObject elementObj)  {\r
650                 Element element = elementObj.getElement();\r
651                 \r
652                 String name = getName(elementObj);//topLevelElement.getName();\r
653                 String className = name;\r
654                 \r
655                 FileWriter fw = new FileWriter();\r
656                 try {\r
657                         fw.writer = createFile(new File(importParserDir.getAbsolutePath()+"/"+className+".java"));\r
658                 } catch (IOException e) {\r
659                         throw new RuntimeException(e);\r
660                 }\r
661                 writers.put(elementObj, fw);\r
662                 boolean isList = false;\r
663                 \r
664                 Pair<String, Boolean> inhertiance = getElementInheritance(elementObj);\r
665                 boolean inherited = inhertiance.second;\r
666                 String baseClass = inhertiance.first;//"org.simantics.xml.sax.base.XMLElementParserBase";\r
667                 \r
668                 \r
669                 provider = getIDProvider(element);\r
670                 List<IDReference> references = getIDReferences(element);\r
671                 UnrecognizedChildElement unknownChildElement = getUnknown(element);\r
672 \r
673                 List<String> intrerfaces = new ArrayList<String>();\r
674                 if (references.size() > 0)\r
675                         intrerfaces.add("org.simantics.xml.sax.base.IDReferenceParser");\r
676                 if (unknownChildElement != null)\r
677                         intrerfaces.add("org.simantics.xml.sax.base.UnrecognizedElementParser");\r
678 \r
679                 createClassHeader(fw.writer, isList);\r
680                 writeClass(fw.writer,false, element.getName(), className, baseClass, intrerfaces);\r
681                 writeIDProvider(fw.writer);\r
682                 fw.writer.println("   @Override");\r
683                 fw.writer.println("   public Resource create(WriteGraph graph, Element element) throws DatabaseException{");\r
684                 fw.writer.println("      Layer0 L0 = Layer0.getInstance(graph);");\r
685                 fw.writer.println("      "+getOntologyImport());\r
686                 if (!isList) {\r
687                 fw.writer.println("      Resource res = graph.newResource();");\r
688                 fw.writer.println("      graph.claim(res, L0.InstanceOf, "+ontShort+name+");");\r
689                 } else {\r
690                 fw.writer.println("      Resource res = ListUtils.create(graph, "+ontShort+name+", Collections.EMPTY_LIST);");\r
691                 }\r
692                 fw.writer.println("      return res;");\r
693                 fw.writer.println("   }");\r
694                 fw.writer.println();\r
695                 \r
696                 fw.writer.println("   @Override");\r
697                 fw.writer.println("   public boolean connectParent(WriteGraph graph, Element parent, Element element) throws DatabaseException{");\r
698                 fw.writer.println("      "+getOntologyImport());\r
699                 fw.writer.println("      graph.claim(parent.getData(), "+this.ontShort+getName(elementObj,"has")+", element.getData());");\r
700                 fw.writer.println("      return true;");\r
701                 fw.writer.println("   }");\r
702                 fw.writer.println();\r
703                 \r
704                 fw.writer.println("   @Override");\r
705                 fw.writer.println("   public void configure(WriteGraph graph, Deque<Element> parents, Element element) throws DatabaseException {");\r
706                 if (inherited) {\r
707                 fw.writer.println("             super.configure(graph,parents,element);");\r
708                 }\r
709                 fw.writer.println("        "+getOntologyImport());\r
710                 \r
711                 LocalComplexType complexType = element.getComplexType();\r
712                 LocalSimpleType simpleType = element.getSimpleType();\r
713                 \r
714                 if (complexType != null) {\r
715                         SchemaObject obj = complexTypes.get(complexType);\r
716                         handleElementComplexTypeAttributes(obj);\r
717                 } \r
718                 fw.writer.println("   }");\r
719                 \r
720                 if (simpleType != null) {\r
721                         SchemaObject obj = simpleTypes.get(simpleType);\r
722                         handleElementSimpleTypeAttributes(obj);\r
723                 }\r
724                 \r
725                 \r
726                 StringWriter stringWriter = new StringWriter();\r
727                 fw.delayedWriter = new PrintWriter(stringWriter);\r
728                 StringWriter stringWriter2 = new StringWriter();\r
729                 fw.delayedWriter2 = new PrintWriter(stringWriter2);\r
730                 \r
731                 fw.writer.println("   public " + className + "() {");\r
732                 fw.writer.println("      super();");\r
733                 \r
734                 if (complexType != null) {\r
735                         SchemaObject obj = complexTypes.get(complexType);\r
736                         handleComplexTypeExtension(obj);\r
737                 } else if (simpleType != null) {\r
738                         \r
739                 }\r
740                 \r
741                 fw.writer.println("   }");\r
742                 \r
743                 fw.writer.println("   @Override");\r
744                 fw.writer.println("   public boolean connectChild(WriteGraph graph, Element element, Element child) throws DatabaseException{");\r
745                 fw.writer.println("      "+getOntologyImport());\r
746                 \r
747                 if (stringWriter.getBuffer().length() > 0) {\r
748                         fw.writer.write(stringWriter.toString());\r
749                 }\r
750                 if (inherited) {\r
751                 fw.writer.println("      return super.connectChild(graph,element,child);");     \r
752                 } else {\r
753                 fw.writer.println("      return false;");\r
754                 }\r
755                 fw.writer.println("   }");\r
756                 fw.writer.println();\r
757                 \r
758                 if (stringWriter2.getBuffer().length() > 0) {\r
759                         fw.writer.write(stringWriter2.toString());\r
760                 }\r
761                 \r
762                 stringWriter = null;\r
763                 fw.delayedWriter.close();\r
764                 fw.delayedWriter = null;\r
765                 stringWriter2 = null;\r
766                 fw.delayedWriter2.close();\r
767                 fw.delayedWriter2 = null;\r
768                 \r
769                 writeIDReferences(fw.writer,name, references);\r
770                 writeUnknownChild(fw.writer,name,unknownChildElement);\r
771 \r
772                 fw.writer.println("}");\r
773                 fw.writer.println();\r
774                 fw.writer.flush();\r
775                 fw.writer.close();\r
776                 fw.writer = null;\r
777                 writers.remove(elementObj);\r
778                 provider = null;\r
779                 \r
780                 ruleClassNames.add(converter.getPluginName()+"."+elementPackageName+"."+name);\r
781         }\r
782         \r
783         private Pair<String,Boolean> getElementInheritance(SchemaObject topLevelElementObj) {\r
784                 Element topLevelElement = topLevelElementObj.getElement();\r
785                 String baseClass = "org.simantics.xml.sax.base.XMLElementNamedChildParserBase";\r
786                 boolean inherited = false;\r
787                 if (topLevelElement.getType() != null) {\r
788                         QName type = topLevelElement.getType();\r
789                         if (!type.getNamespaceURI().equals(SCHEMA_NS)) {\r
790                                 SchemaObject obj = complexTypeName.get(type.getLocalPart());\r
791                                 baseClass = getName(obj);\r
792                                 inherited = true;\r
793                         }       \r
794                 }\r
795                 if (!inherited) {\r
796                         QName type = getElementBase(topLevelElement);\r
797                         if (type != null) {\r
798                                 if (!type.getNamespaceURI().equals(SCHEMA_NS)) {\r
799                                         SchemaObject obj = getWithName(topLevelElementObj, type.getLocalPart());\r
800                                         baseClass = getName(obj);\r
801                                         inherited = true;\r
802                                 }       \r
803                         }\r
804                 }\r
805                 if (!inherited) {\r
806                         QName type = topLevelElement.getSubstitutionGroup();\r
807                         if (type != null) {\r
808                                 if (!type.getNamespaceURI().equals(SCHEMA_NS)) {\r
809                                         SchemaObject obj = getWithName(topLevelElementObj, type.getLocalPart());\r
810                                         baseClass = getName(obj);\r
811                                         inherited = true;\r
812                                 }       \r
813                         }\r
814                 }\r
815                 \r
816                 return new Pair<String, Boolean>(baseClass, inherited);\r
817         }\r
818         \r
819         private void writeClass(PrintWriter writer,boolean abst, String name, String className, String baseClass, List<String> interfaces) {\r
820                 writer.println("@SuppressWarnings(\"unused\")");\r
821                 writer.print("public " +(abst ? "abstract " : "") + "class " + className + " extends "+baseClass);\r
822                 if (interfaces.size() > 0) {\r
823                         writer.print(" implements ");\r
824                         for (int i = 0; i < interfaces.size(); i++) {\r
825                                 writer.print(interfaces.get(i));\r
826                                 if (i < interfaces.size() -1 )\r
827                                         writer.print(",");\r
828                         }\r
829                 }\r
830                 writer.println("{");\r
831                 writer.println();\r
832                 writer.println("   @Override");\r
833                 writer.println("   public java.lang.String getElementId() {");\r
834                 if (name != null)\r
835                 writer.println("      return \""+name+"\";");\r
836                 else // complex types cannot be parsed directly with name/id reference.\r
837                 writer.println("      return null;");\r
838                 writer.println("   }");\r
839                 writer.println();\r
840         }\r
841         \r
842         private void writeIDProvider(PrintWriter writer) {\r
843                 if (provider != null) {\r
844                 writer.println("   java.lang.String idProviderValue = null;");\r
845                 writer.println();\r
846                 writer.println("   @Override");\r
847                 writer.println("   public java.lang.String getID() {");\r
848                 writer.println("        java.lang.String s = idProviderValue;");\r
849                 writer.println("        idProviderValue = null;");\r
850                 writer.println("        return s;");\r
851                 writer.println("   }");\r
852                 writer.println();\r
853                 if (provider.getPriority() != null) {\r
854                 writer.println("   @Override");\r
855                 writer.println("   public int idPriority() {");\r
856                 writer.println("        return " + provider.getPriority().intValue()+";");\r
857                 writer.println("   }"); \r
858                 }\r
859                 }\r
860         }\r
861         \r
862         private void writeIDReferences(PrintWriter writer,String name, List<IDReference> references) {\r
863                 if (references.size() > 0) {\r
864                 writer.println("   @Override");\r
865                 writer.println("   public boolean connectReferences(WriteGraph graph, Element element, java.util.Map<java.lang.String, Element> map) throws DatabaseException {");\r
866                 writer.println("      "+getOntologyImport());\r
867                 writer.println("      boolean result = true;");\r
868                 for (IDReference ref : references) {\r
869                 writer.println("      {");\r
870                 writer.println("         Attribute a = element.getAttribute(\"" + ref.getIDSource().getName() +"\");");\r
871                 writer.println("         if (a != null) {");\r
872                 writer.println("            Element refEle = map.get(a.value);");\r
873                 writer.println("            if (refEle != null) {");\r
874                 writer.println("               Resource ref = refEle.getData();");\r
875                 writer.println("               graph.claim(element.getData(), "+ontShort+name+"_"+ref.getReference().getName()+", ref);");\r
876                 writer.println("            } else {");\r
877                 writer.println("               result = false;");\r
878                 writer.println("            }");\r
879                 writer.println("         }");\r
880                 writer.println("      }");\r
881                 }\r
882                 writer.println("      return result;");\r
883                 writer.println("   }");\r
884                 writer.println();\r
885                 }\r
886         }\r
887         \r
888         private void writeUnknownChild(PrintWriter writer,String name, UnrecognizedChildElement unknownChildElement) {\r
889                 if (unknownChildElement == null)\r
890                         return;\r
891                 \r
892                 writer.println("   @Override");\r
893                 writer.println("   public void configureChild(WriteGraph graph, Deque<Element> parents, Element element, Element child) throws DatabaseException {");\r
894                 writer.println("    " + unknownChildElement.getJavaMethod());\r
895                 writer.println("   }");\r
896                 writer.println();\r
897                 \r
898         }\r
899         \r
900         protected void createClassHeader(PrintWriter writer, boolean isList) {\r
901                 writer.println("package " + converter.getPluginName() +"."+elementPackageName+";");\r
902                 writer.println();\r
903                 writer.println("import java.util.Deque;");\r
904                 writer.println("import org.simantics.databoard.Bindings;");\r
905                 writer.println("import org.simantics.db.Resource;");\r
906                 writer.println("import org.simantics.db.WriteGraph;");\r
907                 writer.println("import org.simantics.db.exception.DatabaseException;");\r
908                 writer.println("import org.simantics.xml.sax.base.Attribute;");\r
909                 writer.println("import org.simantics.xml.sax.base.Element;");\r
910                 if (!isList) {\r
911                 writer.println("import org.simantics.layer0.Layer0;");\r
912             } else {\r
913             writer.println("import java.util.Collections;");\r
914                 writer.println("import org.simantics.db.common.utils.ListUtils;");\r
915                 }\r
916                 writer.println();\r
917         }\r
918         \r
919         private String getOntologyImport() {\r
920                 return this.ontologyClassName+" " +ontShort.substring(0, 3)+" = "+this.ontologyClassName+".getInstance(graph);";\r
921         }\r
922         \r
923         \r
924         private static class FileWriter {\r
925                 public PrintWriter writer;\r
926                 \r
927                 public PrintWriter delayedWriter;\r
928                 public PrintWriter delayedWriter2;\r
929         }\r
930         \r
931         public static String getName(SchemaObject obj) {\r
932                 if (obj.getParent() == null) {\r
933                         switch (obj.getType()) {\r
934                         case COMPLEX_TYPE:\r
935                                 return getComplexTypePrefix()+obj.getName();\r
936                         case ELEMENT:\r
937                                 return obj.getName();\r
938                         case ATTRIBUTE_GROUP:\r
939                                 return getAttributeGroupPrefix()+obj.getName();\r
940                         case SIMPLE_TYPE:\r
941                                 return obj.getName();\r
942                         }\r
943                 } else {\r
944                         SchemaObject o = obj;\r
945                         SchemaObject prev = null;\r
946                         String name = "";\r
947                         while (o != null){\r
948                                 if (o.getName() != null)\r
949                                         name = o.getName()+"_"+name;\r
950                                 prev = o;\r
951                                 o = o.getParent();\r
952                                 if (prev.getObj() instanceof AttributeGroupRef)\r
953                                         o = null;\r
954                         }\r
955                         name = name.substring(0, name.length()-1);\r
956                         switch (prev.getType()) {\r
957                         case COMPLEX_TYPE:\r
958                                 return getComplexTypePrefix()+name;\r
959                         case ELEMENT:\r
960                                 return name;\r
961                         case ATTRIBUTE_GROUP:\r
962                                 return getAttributeGroupPrefix()+name;\r
963                         case SIMPLE_TYPE:\r
964                                 return name;\r
965                         }\r
966                 }\r
967                 throw new RuntimeException();\r
968                 \r
969         }\r
970         \r
971         public static String getName(SchemaObject obj, String rel) {\r
972                 if (obj.getParent() == null) {\r
973                         switch (obj.getType()) {\r
974                         case COMPLEX_TYPE:\r
975                                 return getComplexTypePrefix()+rel+obj.getName();\r
976                         case ELEMENT:\r
977                                 return rel+obj.getName();\r
978                         case ATTRIBUTE_GROUP:\r
979                                 return getAttributeGroupPrefix()+rel+obj.getName();\r
980                         case SIMPLE_TYPE:\r
981                                 return rel+obj.getName();\r
982                         }\r
983                 } else {\r
984                         SchemaObject o = obj;\r
985                         SchemaObject prev = null;\r
986                         String name = "";\r
987                         while (o != null){\r
988                                 if (o.getName() != null)\r
989                                         name = o.getName()+"_"+name;\r
990                                 prev = o;\r
991                                 o = o.getParent();\r
992                         }\r
993                         name = name.substring(0, name.length()-1);\r
994                         switch (prev.getType()) {\r
995                         case COMPLEX_TYPE:\r
996                                 return getComplexTypePrefix()+rel+name;\r
997                         case ELEMENT:\r
998                                 return rel+name;\r
999                         case ATTRIBUTE_GROUP:\r
1000                                 return getAttributeGroupPrefix()+rel+name;\r
1001                         case SIMPLE_TYPE:\r
1002                                 return rel+name;\r
1003                         }\r
1004                 }\r
1005                 throw new RuntimeException();\r
1006                 \r
1007         }\r
1008 }\r