]> gerrit.simantics Code Review - simantics/interop.git/blob - org.simantics.xml.sax.base/src/org/simantics/xml/sax/base/XMLWriter.java
Initial support for XML export (order of Elements is not kept)
[simantics/interop.git] / org.simantics.xml.sax.base / src / org / simantics / xml / sax / base / XMLWriter.java
1 package org.simantics.xml.sax.base;\r
2 \r
3 import java.lang.reflect.Constructor;\r
4 import java.lang.reflect.InvocationTargetException;\r
5 import java.util.Collection;\r
6 import java.util.HashMap;\r
7 import java.util.List;\r
8 import java.util.Map;\r
9 import java.util.Set;\r
10 \r
11 import javax.xml.stream.XMLStreamException;\r
12 import javax.xml.stream.XMLStreamWriter;\r
13 \r
14 import org.eclipse.core.runtime.IStatus;\r
15 import org.eclipse.core.runtime.Status;\r
16 import org.simantics.db.ReadGraph;\r
17 import org.simantics.db.Resource;\r
18 import org.simantics.db.Statement;\r
19 import org.simantics.db.common.utils.ListUtils;\r
20 import org.simantics.db.common.utils.NameUtils;\r
21 import org.simantics.db.exception.DatabaseException;\r
22 import org.simantics.message.ILogger;\r
23 import org.simantics.xml.sax.ontology.XMLResource;\r
24 \r
25 public class XMLWriter {\r
26         \r
27         private ReadGraph graph;\r
28         private Map<String, XMLWriter> subWriters = new HashMap<String, XMLWriter>();\r
29         private Map<Class<? extends XMLElementWriter>, XMLElementWriter> namedWriters = new HashMap<Class<? extends XMLElementWriter>, XMLElementWriter>();\r
30         private Map<Resource,XMLElementWriter> writers = new HashMap<>();\r
31         private String schemaURI;\r
32         \r
33         private ILogger logger;\r
34         \r
35         public ReadGraph getGraph() {\r
36                 return graph;\r
37         }\r
38         \r
39         public void setGraph(ReadGraph graph) {\r
40                 this.graph = graph;\r
41                 for (XMLWriter p : subWriters.values())\r
42                         p.setGraph(graph);\r
43         }\r
44         \r
45         public String getSchemaURI() {\r
46                 return schemaURI;\r
47         }\r
48         \r
49         public void setSchemaURI(String schemaURI) {\r
50                 this.schemaURI = schemaURI;\r
51         }\r
52         \r
53         public void add(XMLElementWriter writer) throws DatabaseException {\r
54                 Resource type = writer.getType(graph);\r
55                 if (type != null)\r
56                         writers.put(type, writer);\r
57                 namedWriters.put(writer.getClass(), writer);\r
58         }\r
59         \r
60         public void add(XMLWriter writer) {\r
61                 subWriters.put(writer.getSchemaURI(), writer);\r
62         }\r
63         \r
64         public void write(Resource root, XMLStreamWriter writer) throws DatabaseException, XMLStreamException {\r
65                 WriterElement element = new WriterElement(root);\r
66                 loadElement(element);\r
67                 write(element, writer);\r
68         }\r
69         \r
70         \r
71         protected void write(WriterElement instance, XMLStreamWriter writer) throws DatabaseException, XMLStreamException {\r
72                 XMLResource XML = XMLResource.getInstance(graph);\r
73 \r
74                 XMLElementWriter elementWriter = instance.writer;\r
75                 elementWriter.start(graph, instance, writer);\r
76                 elementWriter.attributes(graph, instance, graph.getStatements(instance.instance, XML.hasAttribute), writer);\r
77                 if (graph.hasValue(instance.instance))\r
78                         elementWriter.characters(graph, instance, writer);\r
79                 // get all child elements\r
80                 Collection<Statement> childElements = graph.getStatements(instance.instance, XML.hasElement);\r
81                 // load elements, assign writers\r
82                 Map<Resource,WriterElement> elementMap = new HashMap<>();\r
83                 for (Statement s : childElements) {\r
84                         WriterElement c = new WriterElement(instance,s);\r
85                         loadElement(c);\r
86                         elementMap.put(s.getObject(), c);\r
87                 }\r
88                 List<Resource> sorted = elementWriter.children(graph, instance, writer);\r
89                         \r
90                 for (Resource r : sorted) {\r
91                         WriterElement child = elementMap.get(r);\r
92                         write(child, writer);\r
93                 }\r
94                 //write the rest of the elements (in random order) \r
95                 for (Statement stm : childElements) {\r
96                         if (sorted.contains(stm.getObject()))\r
97                                 continue;\r
98                         WriterElement child = elementMap.get(stm.getObject());\r
99                         write(child, writer);\r
100                 }\r
101         \r
102                 elementWriter.end(graph, instance, writer);\r
103                 \r
104         }\r
105         \r
106 //      public void write(Resource root, XMLStreamWriter writer) throws DatabaseException, XMLStreamException {\r
107 //              XMLResource XML = XMLResource.getInstance(graph);\r
108 //              \r
109 //              Deque<Element> stack = new ArrayDeque<>();\r
110 //              Element rootElement = new Element(root);\r
111 //              loadElement(rootElement);\r
112 //              stack.push(rootElement);\r
113 //              while (!stack.isEmpty()) {\r
114 //                      \r
115 //                      Element instance = stack.pop();\r
116 //                      XMLElementWriter elementWriter = instance.writer;\r
117 //                      elementWriter.start(graph, instance.instance, writer);\r
118 //                      elementWriter.attributes(graph, graph.getStatements(instance.instance, XML.hasAttribute), writer);\r
119 //                      // get all child elements\r
120 //                      Collection<Statement> childElements = graph.getStatements(instance.instance, XML.hasElement);\r
121 //                      // get original element order, if available\r
122 //                      Resource originalElementList = graph.getPossibleObject(instance.instance, XML.hasOriginalElementList);\r
123 //                      List<Resource> originalList = null;\r
124 //                      if (originalElementList != null) {\r
125 //                              originalList = ListUtils.toList(graph, originalElementList);\r
126 //                      }\r
127 //                      if (originalList != null) {\r
128 //                              // check for elements that are missing form the original list (should be empty).  \r
129 //                              for (Statement stm : childElements) {\r
130 //                                      if (originalList.contains(stm.getObject()))\r
131 //                                              continue;\r
132 //                                      Element child = new Element(instance,stm.getObject());\r
133 //                                      loadElement(child);\r
134 //                                      stack.push(child);\r
135 //                              }\r
136 //                              // process the list in reverse order so that the stack processing processes the items in correct order.\r
137 //                              for (int i = originalList.size()-1; i >= 0; i--) {\r
138 //                                      Resource r = originalList.get(i);\r
139 //                                      Element child = new Element(instance, r);\r
140 //                                      loadElement(child);\r
141 //                                      stack.push(child);\r
142 //                              }\r
143 //                      } else {\r
144 //                              for (Statement stm : childElements) {\r
145 //                                      Element child = new Element(instance, stm.getObject());\r
146 //                                      loadElement(child);\r
147 //                                      stack.push(child);\r
148 //                              }\r
149 //                      }\r
150 //              }\r
151 //      }\r
152         \r
153         private void loadElement(WriterElement child) throws DatabaseException {\r
154                 XMLElementWriter childWriter = null;\r
155                 if (child.parent != null && child.parent.writer instanceof XMLElementNamedChildWriter) {\r
156                         XMLElementNamedChildWriter namedParentWriter = (XMLElementNamedChildWriter)child.parent.writer;\r
157                         Class<? extends XMLElementWriter> childWriterClass = namedParentWriter.getWriter(graph, writers, child);\r
158                         if (childWriterClass != null) {\r
159                                 childWriter = this.writers.get(childWriterClass);\r
160                                 if (childWriter == null) {\r
161                                         try {\r
162                                                 Constructor<? extends XMLElementWriter> c = childWriterClass.getConstructor(ReadGraph.class);\r
163                                                 //childWriter = childWriterClass.newInstance();\r
164                                                 childWriter = c.newInstance(graph);\r
165                                                 namedWriters.put(childWriterClass, childWriter);\r
166                                         } catch (IllegalAccessException|InstantiationException|NoSuchMethodException|SecurityException|InvocationTargetException e) {\r
167                                                 String err = "Error processing " + childWriterClass.getName() + " : element writers must have accessible constructor with ReadGraph parameter";\r
168                                                 logger.log(new Status(IStatus.ERROR, XMLParser.PLUGIN_ID, err));\r
169                                         } \r
170                                 }\r
171                         }\r
172                 } else {\r
173                         Resource type = graph.getSingleType(child.instance);\r
174                         childWriter = writers.get(type);\r
175                 }\r
176                 if (childWriter == null) {\r
177                         throw new DatabaseException("Cannot locate writer for " + NameUtils.getSafeName(graph, child.instance) + ", " + child.instance);\r
178                 }\r
179                 child.writer = childWriter;\r
180                 \r
181         }\r
182 \r
183 }\r