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