1 package org.simantics.xml.sax.base;
\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
11 import javax.xml.stream.XMLStreamException;
\r
12 import javax.xml.stream.XMLStreamWriter;
\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
25 public class XMLWriter {
\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
33 private ILogger logger;
\r
35 public ReadGraph getGraph() {
\r
39 public void setGraph(ReadGraph graph) {
\r
41 for (XMLWriter p : subWriters.values())
\r
45 public String getSchemaURI() {
\r
49 public void setSchemaURI(String schemaURI) {
\r
50 this.schemaURI = schemaURI;
\r
53 public void add(XMLElementWriter writer) throws DatabaseException {
\r
54 Resource type = writer.getType(graph);
\r
56 writers.put(type, writer);
\r
57 namedWriters.put(writer.getClass(), writer);
\r
60 public void add(XMLWriter writer) {
\r
61 subWriters.put(writer.getSchemaURI(), writer);
\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
71 protected void write(WriterElement instance, XMLStreamWriter writer) throws DatabaseException, XMLStreamException {
\r
72 XMLResource XML = XMLResource.getInstance(graph);
\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
86 elementMap.put(s.getObject(), c);
\r
88 List<Resource> sorted = elementWriter.children(graph, instance, writer);
\r
90 for (Resource r : sorted) {
\r
91 WriterElement child = elementMap.get(r);
\r
92 write(child, writer);
\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
98 WriterElement child = elementMap.get(stm.getObject());
\r
99 write(child, writer);
\r
102 elementWriter.end(graph, instance, writer);
\r
106 // public void write(Resource root, XMLStreamWriter writer) throws DatabaseException, XMLStreamException {
\r
107 // XMLResource XML = XMLResource.getInstance(graph);
\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
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
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
132 // Element child = new Element(instance,stm.getObject());
\r
133 // loadElement(child);
\r
134 // stack.push(child);
\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
144 // for (Statement stm : childElements) {
\r
145 // Element child = new Element(instance, stm.getObject());
\r
146 // loadElement(child);
\r
147 // stack.push(child);
\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
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
173 Resource type = graph.getSingleType(child.instance);
\r
174 childWriter = writers.get(type);
\r
176 if (childWriter == null) {
\r
177 throw new DatabaseException("Cannot locate writer for " + NameUtils.getSafeName(graph, child.instance) + ", " + child.instance);
\r
179 child.writer = childWriter;
\r