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;fp=org.simantics.xml.sax.base%2Fsrc%2Forg%2Fsimantics%2Fxml%2Fsax%2Fbase%2FXMLWriter.java;h=dba343b59e71462c4efb87e88e5f070b1c2e624c;hb=5985d5ea605049222dc5a4acb0accf77afd8f76f;hp=ce5cb90068aa16cedfa7483ae04d00dbeb0c4780;hpb=8c7637425667bd9710be0fe6afe437050fea59b7;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 ce5cb90..dba343b 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 @@ -1,213 +1,272 @@ -package org.simantics.xml.sax.base; - -import java.lang.reflect.Constructor; -import java.lang.reflect.InvocationTargetException; -import java.util.HashMap; -import java.util.HashSet; -import java.util.LinkedHashSet; -import java.util.List; -import java.util.Map; -import java.util.Set; - -import javax.xml.stream.XMLStreamException; -import javax.xml.stream.XMLStreamWriter; - -import org.eclipse.core.runtime.IStatus; -import org.eclipse.core.runtime.Status; -import org.simantics.db.ReadGraph; -import org.simantics.db.Resource; -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, XMLElementWriter> namedWriters = new HashMap, XMLElementWriter>(); - private Map writers = new HashMap<>(); - private String schemaURI; - private String ontologyURI; - private Resource ontology; - - private ILogger logger; - - public ReadGraph getGraph() { - return 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() { - return schemaURI; - } - - public void setSchemaURI(String schemaURI) { - 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) - writers.put(type, writer); - namedWriters.put(writer.getClass(), writer); - } - - public void add(XMLWriter writer) { - subWriters.put(writer.getOntology(), writer); - } - - public void write(Resource root, XMLStreamWriter writer) throws DatabaseException, XMLStreamException { - WriterElement element = new WriterElement(root); - loadElement(element); - write(element, writer); - } - - - protected void write(WriterElement instance, XMLStreamWriter writer) throws DatabaseException, XMLStreamException { - XMLResource XML = XMLResource.getInstance(graph); - - 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 - 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) { - WriterElement c = new WriterElement(instance,s); - loadElement(c); - elementMap.put(s.getObject(), c); - } - 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 (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); - } - - elementWriter.end(graph, instance, writer); - - } - - private void loadElement(WriterElement child) throws DatabaseException { - XMLElementWriter childWriter = null; - if (child.parent != null && child.parent.writer instanceof XMLElementNamedChildWriter) { - XMLElementNamedChildWriter namedParentWriter = (XMLElementNamedChildWriter)child.parent.writer; - Class childWriterClass = namedParentWriter.getWriter(graph, writers, child); - if (childWriterClass != null) { - childWriter = this.writers.get(childWriterClass); - if (childWriter == null) { - try { - 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, e)); - } - } - } - } else { - Resource type = graph.getSingleType(child.instance); - childWriter = writers.get(type); - } - if (childWriter == null) { - // 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; - } - -} +package org.simantics.xml.sax.base; + +import java.lang.reflect.Constructor; +import java.lang.reflect.InvocationTargetException; +import java.util.HashMap; +import java.util.HashSet; +import java.util.LinkedHashSet; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; +import java.util.Set; + +import javax.xml.stream.XMLStreamException; +import javax.xml.stream.XMLStreamWriter; + +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Status; +import org.simantics.db.ReadGraph; +import org.simantics.db.Resource; +import org.simantics.db.Session; +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, XMLElementWriter> namedWriters = new HashMap, XMLElementWriter>(); + private Map writers = new HashMap<>(); + private String schemaURI; + private String ontologyURI; + private Resource ontology; + + private ILogger logger; + + protected Map nsPrefixes; + + public ReadGraph getGraph() { + return 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() { + return schemaURI; + } + + public void setSchemaURI(String schemaURI) { + 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) + writers.put(type, writer); + namedWriters.put(writer.getClass(), writer); + } + + public void add(XMLWriter writer) { + subWriters.put(writer.getOntology(), writer); + } + + public void configureWriter(XMLStreamWriter writer) throws XMLStreamException { + if (nsPrefixes == null) + return; + for (Entry nsEntry : nsPrefixes.entrySet()) { + writer.setPrefix(nsEntry.getValue(), nsEntry.getKey()); + } + + } + + public void writeNS(XMLStreamWriter writer) throws XMLStreamException { + if (nsPrefixes == null) + return; + for (Entry nsEntry : nsPrefixes.entrySet()) { + writer.writeNamespace(nsEntry.getValue(), nsEntry.getKey()); + } + + } + + public XMLWriter resolveDependencies(Session session) throws DatabaseException { + java.util.Map map = new java.util.HashMap<>(); + map.put(this.schemaURI, this); + addDependencies(session,map); + nsPrefixes = new HashMap<>(); + int i = 0; + for (String ns : map.keySet()) { + if (this.schemaURI.equals(ns)) + continue; + if (!nsPrefixes.containsKey(ns)) { + nsPrefixes.put(ns, "ns"+i); + i++; + } + } + return this; + } + + public void addDependencies(Session session,java.util.Map map) throws DatabaseException { + + } + + public void write(Resource root, XMLStreamWriter writer) throws DatabaseException, XMLStreamException { + WriterElement element = new WriterElement(root); + loadElement(element); + write(element, writer); + } + + + protected void write(WriterElement instance, XMLStreamWriter writer) throws DatabaseException, XMLStreamException { + XMLResource XML = XMLResource.getInstance(graph); + + 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); + this.configureWriter(writer); + this.writeNS(writer); + } + + 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 + 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) { + WriterElement c = new WriterElement(instance,s); + loadElement(c); + elementMap.put(s.getObject(), c); + } + 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 (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); + } + + elementWriter.end(graph, instance, writer); + + } + + private void loadElement(WriterElement child) throws DatabaseException { + if (child.instance.getResourceId() == 983084L) + System.out.println(); + XMLElementWriter childWriter = null; + if (child.parent != null && child.parent.writer instanceof XMLElementNamedChildWriter) { + XMLElementNamedChildWriter namedParentWriter = (XMLElementNamedChildWriter)child.parent.writer; + Class childWriterClass = namedParentWriter.getWriter(graph, writers, child); + if (childWriterClass != null) { + childWriter = this.writers.get(childWriterClass); + if (childWriter == null) { + try { + 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, e)); + } + } + } + } else { + Resource type = graph.getSingleType(child.instance); + childWriter = writers.get(type); + } + if (childWriter == null) { + // try child ontology/schema + //Resource type = graph.getSingleType(child.instance); + // hack fix for elements containing character data (Current schema conversion does not recognise such cases, leaving Literal type inheritance out). + XMLResource XML = XMLResource.getInstance(graph); + Resource type = graph.getSingleType(child.instance,XML.Element); + Resource ontology = getOntology(type); + if (ontology != null) { + XMLWriter xmlWriter = subWriters.get(ontology); + if (xmlWriter == null) { + // FIXME: We need better way to resolve correct ontology and writer. + for (XMLWriter w : subWriters.values()) { + xmlWriter = w.subWriters.get(ontology); + if (xmlWriter != null) + break; + } + } + 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; + } + +}