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.HashSet;
\r
8 import java.util.LinkedHashSet;
\r
9 import java.util.List;
\r
10 import java.util.Map;
\r
11 import java.util.Set;
\r
13 import javax.xml.stream.XMLStreamException;
\r
14 import javax.xml.stream.XMLStreamWriter;
\r
16 import org.eclipse.core.runtime.IStatus;
\r
17 import org.eclipse.core.runtime.Status;
\r
18 import org.simantics.db.ReadGraph;
\r
19 import org.simantics.db.Resource;
\r
20 import org.simantics.db.Statement;
\r
21 import org.simantics.db.common.utils.ListUtils;
\r
22 import org.simantics.db.common.utils.NameUtils;
\r
23 import org.simantics.db.exception.DatabaseException;
\r
24 import org.simantics.message.ILogger;
\r
25 import org.simantics.xml.sax.ontology.XMLResource;
\r
27 public class XMLWriter {
\r
29 private ReadGraph graph;
\r
30 private Map<String, XMLWriter> subWriters = new HashMap<String, XMLWriter>();
\r
31 private Map<Class<? extends XMLElementWriter>, XMLElementWriter> namedWriters = new HashMap<Class<? extends XMLElementWriter>, XMLElementWriter>();
\r
32 private Map<Resource,XMLElementWriter> writers = new HashMap<>();
\r
33 private String schemaURI;
\r
35 private ILogger logger;
\r
37 public ReadGraph getGraph() {
\r
41 public void setGraph(ReadGraph graph) {
\r
43 for (XMLWriter p : subWriters.values())
\r
47 public String getSchemaURI() {
\r
51 public void setSchemaURI(String schemaURI) {
\r
52 this.schemaURI = schemaURI;
\r
55 public void add(XMLElementWriter writer) throws DatabaseException {
\r
56 Resource type = writer.getType(graph);
\r
58 writers.put(type, writer);
\r
59 namedWriters.put(writer.getClass(), writer);
\r
62 public void add(XMLWriter writer) {
\r
63 subWriters.put(writer.getSchemaURI(), writer);
\r
66 public void write(Resource root, XMLStreamWriter writer) throws DatabaseException, XMLStreamException {
\r
67 WriterElement element = new WriterElement(root);
\r
68 loadElement(element);
\r
69 write(element, writer);
\r
73 protected void write(WriterElement instance, XMLStreamWriter writer) throws DatabaseException, XMLStreamException {
\r
74 XMLResource XML = XMLResource.getInstance(graph);
\r
76 XMLElementWriter elementWriter = instance.writer;
\r
77 elementWriter.start(graph, instance, writer);
\r
78 if (instance.parent == null) {
\r
79 if(getSchemaURI() != null) {
\r
80 writer.writeDefaultNamespace(getSchemaURI());
\r
83 elementWriter.attributes(graph, instance, graph.getStatements(instance.instance, XML.hasAttribute), writer);
\r
84 if (graph.hasValue(instance.instance))
\r
85 elementWriter.characters(graph, instance, writer);
\r
86 // get all child elements
\r
87 Collection<Statement> childElements = graph.getStatements(instance.instance, XML.hasElement);
\r
88 // load elements, assign writers
\r
89 Map<Resource,WriterElement> elementMap = new HashMap<>();
\r
90 for (Statement s : childElements) {
\r
91 WriterElement c = new WriterElement(instance,s);
\r
93 elementMap.put(s.getObject(), c);
\r
95 LinkedHashSet<Resource> sorted = new LinkedHashSet<>();
\r
96 if (graph.hasStatement(instance.instance, XML.hasOriginalElementList)) {
\r
97 Resource originalList = graph.getSingleObject(instance.instance, XML.hasOriginalElementList);
\r
98 List<Resource> l = ListUtils.toList(graph, originalList);
\r
101 elementWriter.children(graph, instance, sorted);
\r
102 Set<Resource> processed = new HashSet<>();
\r
103 for (Resource r : sorted) {
\r
104 if (processed.contains(r)) // badly generated writer could report elements several times.
\r
106 WriterElement child = elementMap.get(r);
\r
107 write(child, writer);
\r
110 //write the rest of the elements (in random order)
\r
111 for (Statement stm : childElements) {
\r
112 if (processed.contains(stm.getObject()))
\r
114 WriterElement child = elementMap.get(stm.getObject());
\r
115 write(child, writer);
\r
118 elementWriter.end(graph, instance, writer);
\r
122 private void loadElement(WriterElement child) throws DatabaseException {
\r
123 XMLElementWriter childWriter = null;
\r
124 if (child.parent != null && child.parent.writer instanceof XMLElementNamedChildWriter) {
\r
125 XMLElementNamedChildWriter namedParentWriter = (XMLElementNamedChildWriter)child.parent.writer;
\r
126 Class<? extends XMLElementWriter> childWriterClass = namedParentWriter.getWriter(graph, writers, child);
\r
127 if (childWriterClass != null) {
\r
128 childWriter = this.writers.get(childWriterClass);
\r
129 if (childWriter == null) {
\r
131 Constructor<? extends XMLElementWriter> c = childWriterClass.getConstructor(ReadGraph.class);
\r
132 //childWriter = childWriterClass.newInstance();
\r
133 childWriter = c.newInstance(graph);
\r
134 namedWriters.put(childWriterClass, childWriter);
\r
135 } catch (IllegalAccessException|InstantiationException|NoSuchMethodException|SecurityException|InvocationTargetException e) {
\r
136 String err = "Error processing " + childWriterClass.getName() + " : element writers must have accessible constructor with ReadGraph parameter";
\r
137 logger.log(new Status(IStatus.ERROR, XMLParser.PLUGIN_ID, err));
\r
142 Resource type = graph.getSingleType(child.instance);
\r
143 childWriter = writers.get(type);
\r
145 if (childWriter == null) {
\r
146 throw new DatabaseException("Cannot locate writer for " + NameUtils.getSafeName(graph, child.instance) + ", " + child.instance);
\r
148 child.writer = childWriter;
\r