X-Git-Url: https://gerrit.simantics.org/r/gitweb?a=blobdiff_plain;f=org.simantics.xml.sax.base%2Fsrc%2Forg%2Fsimantics%2Fxml%2Fsax%2Fbase%2FXMLWriter.java;h=ce5cb90068aa16cedfa7483ae04d00dbeb0c4780;hb=c8ead11dcd815dc26885b2b8e866e4ac4e563ae5;hp=3fd881ba3c3d86da100a06c87190c32a06f54512;hpb=dd3b2c7ecd5f4b60734f2602b16637aa8be2a263;p=simantics%2Finterop.git diff --git a/org.simantics.xml.sax.base/src/org/simantics/xml/sax/base/XMLWriter.java b/org.simantics.xml.sax.base/src/org/simantics/xml/sax/base/XMLWriter.java index 3fd881b..ce5cb90 100644 --- a/org.simantics.xml.sax.base/src/org/simantics/xml/sax/base/XMLWriter.java +++ b/org.simantics.xml.sax.base/src/org/simantics/xml/sax/base/XMLWriter.java @@ -2,8 +2,9 @@ package org.simantics.xml.sax.base; import java.lang.reflect.Constructor; import java.lang.reflect.InvocationTargetException; -import java.util.Collection; import java.util.HashMap; +import java.util.HashSet; +import java.util.LinkedHashSet; import java.util.List; import java.util.Map; import java.util.Set; @@ -19,16 +20,22 @@ import org.simantics.db.Statement; import org.simantics.db.common.utils.ListUtils; import org.simantics.db.common.utils.NameUtils; import org.simantics.db.exception.DatabaseException; +import org.simantics.layer0.Layer0; import org.simantics.message.ILogger; import org.simantics.xml.sax.ontology.XMLResource; public class XMLWriter { + public static String XML_SCHEMA_URI = "http://www.w3.org/2001/XMLSchema"; + public static String XML_SCHEMA_INSTANCE_URI = "http://www.w3.org/2001/XMLSchema-instance"; + private ReadGraph graph; - private Map subWriters = new HashMap(); + private Map subWriters = new HashMap(); private Map, XMLElementWriter> namedWriters = new HashMap, XMLElementWriter>(); private Map writers = new HashMap<>(); private String schemaURI; + private String ontologyURI; + private Resource ontology; private ILogger logger; @@ -36,10 +43,12 @@ public class XMLWriter { return graph; } - public void setGraph(ReadGraph graph) { + public void setGraph(ReadGraph graph) throws DatabaseException { this.graph = graph; for (XMLWriter p : subWriters.values()) p.setGraph(graph); + if (ontologyURI != null) + this.ontology = graph.getResource(ontologyURI); } public String getSchemaURI() { @@ -50,6 +59,18 @@ public class XMLWriter { this.schemaURI = schemaURI; } + public String getOntologyURI() { + return ontologyURI; + } + + public void setOntologyURI(String ontologyURI) { + this.ontologyURI = ontologyURI; + } + + public Resource getOntology() { + return ontology; + } + public void add(XMLElementWriter writer) throws DatabaseException { Resource type = writer.getType(graph); if (type != null) @@ -58,7 +79,7 @@ public class XMLWriter { } public void add(XMLWriter writer) { - subWriters.put(writer.getSchemaURI(), writer); + subWriters.put(writer.getOntology(), writer); } public void write(Resource root, XMLStreamWriter writer) throws DatabaseException, XMLStreamException { @@ -73,11 +94,20 @@ public class XMLWriter { XMLElementWriter elementWriter = instance.writer; elementWriter.start(graph, instance, writer); + if (instance.parent == null) { + if(getSchemaURI() != null) { + writer.writeDefaultNamespace(getSchemaURI()); + } + writer.writeNamespace("xsd", XML_SCHEMA_URI); + writer.writeNamespace("xsi", XML_SCHEMA_INSTANCE_URI); + } elementWriter.attributes(graph, instance, graph.getStatements(instance.instance, XML.hasAttribute), writer); if (graph.hasValue(instance.instance)) elementWriter.characters(graph, instance, writer); // get all child elements - Collection childElements = graph.getStatements(instance.instance, XML.hasElement); + Set childElements = new HashSet<>(); + childElements.addAll(graph.getStatements(instance.instance, XML.hasElement)); + childElements.addAll(graph.getStatements(instance.instance, XML.hasComplexType)); // load elements, assign writers Map elementMap = new HashMap<>(); for (Statement s : childElements) { @@ -85,17 +115,30 @@ public class XMLWriter { loadElement(c); elementMap.put(s.getObject(), c); } - List sorted = elementWriter.children(graph, instance, writer); - + LinkedHashSet sorted = new LinkedHashSet<>(); + if (graph.hasStatement(instance.instance, XML.hasOriginalElementList)) { + Resource originalList = graph.getSingleObject(instance.instance, XML.hasOriginalElementList); + List l = ListUtils.toList(graph, originalList); + sorted.addAll(l); + } + elementWriter.children(graph, instance, sorted); + Set processed = new HashSet<>(); for (Resource r : sorted) { + if (processed.contains(r)) // badly generated writer could report elements several times. + continue; WriterElement child = elementMap.get(r); + if (child == null) + throw new DatabaseException("Trying to export unregonized resource " +NameUtils.getSafeName(graph, r) + " " + r); write(child, writer); + processed.add(r); } //write the rest of the elements (in random order) for (Statement stm : childElements) { - if (sorted.contains(stm.getObject())) + if (processed.contains(stm.getObject())) continue; WriterElement child = elementMap.get(stm.getObject()); + if (child == null) + throw new DatabaseException("Trying to export unregonized resource " +NameUtils.getSafeName(graph, stm.getObject()) + " " + stm.getObject()); write(child, writer); } @@ -103,53 +146,6 @@ public class XMLWriter { } -// public void write(Resource root, XMLStreamWriter writer) throws DatabaseException, XMLStreamException { -// XMLResource XML = XMLResource.getInstance(graph); -// -// Deque stack = new ArrayDeque<>(); -// Element rootElement = new Element(root); -// loadElement(rootElement); -// stack.push(rootElement); -// while (!stack.isEmpty()) { -// -// Element instance = stack.pop(); -// XMLElementWriter elementWriter = instance.writer; -// elementWriter.start(graph, instance.instance, writer); -// elementWriter.attributes(graph, graph.getStatements(instance.instance, XML.hasAttribute), writer); -// // get all child elements -// Collection childElements = graph.getStatements(instance.instance, XML.hasElement); -// // get original element order, if available -// Resource originalElementList = graph.getPossibleObject(instance.instance, XML.hasOriginalElementList); -// List originalList = null; -// if (originalElementList != null) { -// originalList = ListUtils.toList(graph, originalElementList); -// } -// if (originalList != null) { -// // check for elements that are missing form the original list (should be empty). -// for (Statement stm : childElements) { -// if (originalList.contains(stm.getObject())) -// continue; -// Element child = new Element(instance,stm.getObject()); -// loadElement(child); -// stack.push(child); -// } -// // process the list in reverse order so that the stack processing processes the items in correct order. -// for (int i = originalList.size()-1; i >= 0; i--) { -// Resource r = originalList.get(i); -// Element child = new Element(instance, r); -// loadElement(child); -// stack.push(child); -// } -// } else { -// for (Statement stm : childElements) { -// Element child = new Element(instance, stm.getObject()); -// loadElement(child); -// stack.push(child); -// } -// } -// } -// } - private void loadElement(WriterElement child) throws DatabaseException { XMLElementWriter childWriter = null; if (child.parent != null && child.parent.writer instanceof XMLElementNamedChildWriter) { @@ -159,13 +155,18 @@ public class XMLWriter { childWriter = this.writers.get(childWriterClass); if (childWriter == null) { try { - Constructor c = childWriterClass.getConstructor(ReadGraph.class); - //childWriter = childWriterClass.newInstance(); - childWriter = c.newInstance(graph); + Constructor c = null; + try { + c = childWriterClass.getConstructor(ReadGraph.class); + childWriter = c.newInstance(graph); + } catch (NoSuchMethodException e) { + c = childWriterClass.getConstructor(); + childWriter = c.newInstance(); + } namedWriters.put(childWriterClass, childWriter); } catch (IllegalAccessException|InstantiationException|NoSuchMethodException|SecurityException|InvocationTargetException e) { String err = "Error processing " + childWriterClass.getName() + " : element writers must have accessible constructor with ReadGraph parameter"; - logger.log(new Status(IStatus.ERROR, XMLParser.PLUGIN_ID, err)); + logger.log(new Status(IStatus.ERROR, XMLParser.PLUGIN_ID, err, e)); } } } @@ -174,10 +175,39 @@ public class XMLWriter { childWriter = writers.get(type); } if (childWriter == null) { - throw new DatabaseException("Cannot locate writer for " + NameUtils.getSafeName(graph, child.instance) + ", " + child.instance); + // try child ontology/schema + Resource type = graph.getSingleType(child.instance); + Resource ontology = getOntology(type); + if (ontology != null) { + XMLWriter xmlWriter = subWriters.get(ontology); + if (xmlWriter != null) { + childWriter = xmlWriter.writers.get(type); + // wrap the child writer with namespace writer + if (childWriter != null) { + if (childWriter instanceof XMLElementNamedChildWriter) { + childWriter = new XMLNSNamedChildWriter((XMLElementNamedChildWriter)childWriter, xmlWriter.schemaURI); + } else { + childWriter = new XMLNSElementWriter(childWriter, xmlWriter.schemaURI); + } + } + } + } + if (childWriter == null) + throw new DatabaseException("Cannot locate writer for " + NameUtils.getSafeName(graph, child.instance) + ", " + child.instance); } child.writer = childWriter; } + + private Resource getOntology(Resource type) throws DatabaseException { + Layer0 L0 = Layer0.getInstance(graph); + Resource r = type; + while (true) { + r = graph.getPossibleObject(r, L0.PartOf); + if (r != null && graph.isInstanceOf(r, L0.Ontology)) + break; + } + return r; + } }