From 5985d5ea605049222dc5a4acb0accf77afd8f76f Mon Sep 17 00:00:00 2001 From: Marko Luukkainen Date: Fri, 5 Oct 2018 18:22:55 +0300 Subject: [PATCH] Attribute namespace + multi-schema data export gitlab #3 Change-Id: I7eb6cdae8be3be31301a0c4a2b5e59365c4d7293 --- .../base/XMLElementNamedChildWriterBase.java | 220 ++++---- .../org/simantics/xml/sax/base/XMLParser.java | 18 +- .../org/simantics/xml/sax/base/XMLWriter.java | 485 ++++++++++-------- .../simantics/xml/data/XmlDataConverter.java | 35 +- .../simantics/xml/sax/ExporterGenerator.java | 62 ++- .../simantics/xml/sax/ImporterGenerator.java | 17 +- .../xml/sax/SchemaConversionBase.java | 43 +- .../org/simantics/xml/sax/SchemaObject.java | 23 +- 8 files changed, 522 insertions(+), 381 deletions(-) diff --git a/org.simantics.xml.sax.base/src/org/simantics/xml/sax/base/XMLElementNamedChildWriterBase.java b/org.simantics.xml.sax.base/src/org/simantics/xml/sax/base/XMLElementNamedChildWriterBase.java index 8e6a678..32ad6f1 100644 --- a/org.simantics.xml.sax.base/src/org/simantics/xml/sax/base/XMLElementNamedChildWriterBase.java +++ b/org.simantics.xml.sax.base/src/org/simantics/xml/sax/base/XMLElementNamedChildWriterBase.java @@ -1,108 +1,112 @@ -package org.simantics.xml.sax.base; - -import java.util.HashMap; -import java.util.HashSet; -import java.util.Map; -import java.util.Set; - -import javax.xml.stream.XMLStreamException; -import javax.xml.stream.XMLStreamWriter; - -import org.simantics.db.ReadGraph; -import org.simantics.db.Resource; -import org.simantics.db.exception.DatabaseException; - -public abstract class XMLElementNamedChildWriterBase implements XMLElementNamedChildWriter{ - - private Map> typeWriters = new HashMap<>(); - private Map> relationWriters = new HashMap<>(); - private Map>> relationTypeWriters = new HashMap<>(); - private Set> writers = new HashSet>(); - - - public XMLElementNamedChildWriterBase() { - - } - - public XMLElementNamedChildWriterBase(ReadGraph graph) { - - } - - @Override - public Resource getType(ReadGraph graph) throws DatabaseException { - return null; - } - - @Override - public void start(ReadGraph graph, WriterElement instance, XMLStreamWriter writer) throws XMLStreamException { - writer.writeStartElement(getElementId()); - } - - @Override - public void characters(ReadGraph graph, WriterElement instance, XMLStreamWriter writer) - throws XMLStreamException, DatabaseException { - - } - - @Override - public void end(ReadGraph graph, WriterElement instance, XMLStreamWriter writer) throws XMLStreamException { - writer.writeEndElement(); - } - - @Override - public void children(ReadGraph graph, WriterElement instance, Set sorted) - throws XMLStreamException, DatabaseException { - - } - - @Override - public Class getWriter(ReadGraph graph, Map writers, WriterElement child) throws DatabaseException{ - Resource type = graph.getSingleType(child.instance); - Class writerClass = typeWriters.get(type); - if (writerClass != null) - return writerClass; - if (child.statement != null) { - Map> typeWriters = relationTypeWriters.get(child.statement.getPredicate()); - if (typeWriters != null) { - writerClass = typeWriters.get(type); - if (writerClass != null) - return writerClass; - } - writerClass = relationWriters.get(child.statement.getPredicate()); - if (writerClass != null) - return writerClass; - } - XMLElementWriter writer = writers.get(type); - if (writer == null) - return null; - writerClass = writer.getClass(); - if (this.writers.contains(writerClass)) - return writerClass; - for (Class c : this.writers) - if (c.isAssignableFrom(writerClass)) - return writerClass; - return null; - } - - public void addTypeWriter(Resource type, Class writer) { - typeWriters.put(type, writer); - } - - public void addRelationWriter(Resource relation, Class writer) { - relationWriters.put(relation, writer); - } - - public void addRelationTypeWriter(Resource relation, Resource type, Class writer) { - Map> typeWriters = relationTypeWriters.get(relation); - if (typeWriters == null) { - typeWriters = new HashMap<>(); - relationTypeWriters.put(relation, typeWriters); - } - typeWriters.put(type, writer); - } - - - public void addWriter(Class writer) { - writers.add(writer); - } -} +package org.simantics.xml.sax.base; + +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; + +import javax.xml.stream.XMLStreamException; +import javax.xml.stream.XMLStreamWriter; + +import org.simantics.db.ReadGraph; +import org.simantics.db.Resource; +import org.simantics.db.exception.DatabaseException; +import org.simantics.xml.sax.ontology.XMLResource; + +public abstract class XMLElementNamedChildWriterBase implements XMLElementNamedChildWriter{ + + private Map> typeWriters = new HashMap<>(); + private Map> relationWriters = new HashMap<>(); + private Map>> relationTypeWriters = new HashMap<>(); + private Set> writers = new HashSet>(); + + + public XMLElementNamedChildWriterBase() { + + } + + public XMLElementNamedChildWriterBase(ReadGraph graph) { + + } + + @Override + public Resource getType(ReadGraph graph) throws DatabaseException { + return null; + } + + @Override + public void start(ReadGraph graph, WriterElement instance, XMLStreamWriter writer) throws XMLStreamException { + writer.writeStartElement(getElementId()); + } + + @Override + public void characters(ReadGraph graph, WriterElement instance, XMLStreamWriter writer) + throws XMLStreamException, DatabaseException { + + } + + @Override + public void end(ReadGraph graph, WriterElement instance, XMLStreamWriter writer) throws XMLStreamException { + writer.writeEndElement(); + } + + @Override + public void children(ReadGraph graph, WriterElement instance, Set sorted) + throws XMLStreamException, DatabaseException { + + } + + @Override + public Class getWriter(ReadGraph graph, Map writers, WriterElement child) throws DatabaseException{ + //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); + Class writerClass = typeWriters.get(type); + if (writerClass != null) + return writerClass; + if (child.statement != null) { + Map> typeWriters = relationTypeWriters.get(child.statement.getPredicate()); + if (typeWriters != null) { + writerClass = typeWriters.get(type); + if (writerClass != null) + return writerClass; + } + writerClass = relationWriters.get(child.statement.getPredicate()); + if (writerClass != null) + return writerClass; + } + XMLElementWriter writer = writers.get(type); + if (writer == null) + return null; + writerClass = writer.getClass(); + if (this.writers.contains(writerClass)) + return writerClass; + for (Class c : this.writers) + if (c.isAssignableFrom(writerClass)) + return writerClass; + return null; + } + + public void addTypeWriter(Resource type, Class writer) { + typeWriters.put(type, writer); + } + + public void addRelationWriter(Resource relation, Class writer) { + relationWriters.put(relation, writer); + } + + public void addRelationTypeWriter(Resource relation, Resource type, Class writer) { + Map> typeWriters = relationTypeWriters.get(relation); + if (typeWriters == null) { + typeWriters = new HashMap<>(); + relationTypeWriters.put(relation, typeWriters); + } + typeWriters.put(type, writer); + } + + + public void addWriter(Class writer) { + writers.add(writer); + } +} diff --git a/org.simantics.xml.sax.base/src/org/simantics/xml/sax/base/XMLParser.java b/org.simantics.xml.sax.base/src/org/simantics/xml/sax/base/XMLParser.java index 3d708f4..44530c0 100644 --- a/org.simantics.xml.sax.base/src/org/simantics/xml/sax/base/XMLParser.java +++ b/org.simantics.xml.sax.base/src/org/simantics/xml/sax/base/XMLParser.java @@ -100,10 +100,10 @@ public class XMLParser extends DefaultHandler implements Serializable { private List idReferenceElements = new ArrayList(); - private void loadElement(Deque parents, ParserElement element) throws SAXException{ - loadElement(parents, element, true); + private boolean loadElement(Deque parents, ParserElement element) throws SAXException{ + return loadElement(parents, element, true); } - private void loadElement(Deque parents, ParserElement element, boolean checkParent) throws SAXException{ + private boolean loadElement(Deque parents, ParserElement element, boolean checkParent) throws SAXException{ XMLElementParser parser = null; ParserElement parent = null; if (parents.size() > 0) { @@ -113,8 +113,8 @@ public class XMLParser extends DefaultHandler implements Serializable { if (checkParent && parent.getXMLParser() != null && parent.getXMLParser() != this) { //element.setXMLParser(parent.getXMLParser()); element.setXMLParser(parent.getXMLParser()); - parent.getXMLParser().loadElement(parents, element); - return; + if (parent.getXMLParser().loadElement(parents, element)) + return true; } if (parent.getElementParser() instanceof XMLElementNamedChildParser) { // use parent's named child parser if it is supported @@ -150,6 +150,7 @@ public class XMLParser extends DefaultHandler implements Serializable { if (parser instanceof IDReferenceParser) idReferenceElements.add(element); element.setElementParser(parser); + return true; } catch (DatabaseException e) { throw new SAXException(e); } @@ -159,12 +160,14 @@ public class XMLParser extends DefaultHandler implements Serializable { String nsRef[] = element.getQName().split(":"); if (schemaRef != null && subParsers.containsKey(schemaRef.value)) { XMLParser subParser = subParsers.get(schemaRef.value); - subParser.loadElement(parents, element); + boolean b = subParser.loadElement(parents, element); element.setXMLParser(subParser); + return b; } else if (nsRef.length == 2 && element.getNS(nsRef[0]) != null && subParsers.containsKey(element.getNS(nsRef[0]))) { XMLParser subParser = subParsers.get(element.getNS(nsRef[0])); - subParser.loadElement(parents, element, false); + boolean b = subParser.loadElement(parents, element, false); element.setXMLParser(subParser); + return b; } else { if (parent == null && parents.size() > 0) parent = parents.peek(); @@ -178,6 +181,7 @@ public class XMLParser extends DefaultHandler implements Serializable { logger.log(new Status(IStatus.ERROR, PLUGIN_ID, err)); if (debug) System.err.println(err); + return false; } } } 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; + } + +} diff --git a/org.simantics.xml.sax/src/org/simantics/xml/data/XmlDataConverter.java b/org.simantics.xml.sax/src/org/simantics/xml/data/XmlDataConverter.java index ce38d5e..7a2a5c5 100644 --- a/org.simantics.xml.sax/src/org/simantics/xml/data/XmlDataConverter.java +++ b/org.simantics.xml.sax/src/org/simantics/xml/data/XmlDataConverter.java @@ -174,15 +174,12 @@ public class XmlDataConverter { } else { schemaElement = elementMap.get(s).get(elementName); } - if (elementName.equals("CanvasLayers.TracingLayer") || elementName.equals("Layer")) - System.out.println(); Element parentElement = elementStack.peek(); boolean newElement = false; boolean sameNameSpace = true; if (parentElement != null) { - //QName parentType = parentElement.getType(); String parentNs = elementNsMap.get(parentElement); sameNameSpace =currentNS.equals(parentNs); if (!sameNameSpace) { @@ -192,26 +189,12 @@ public class XmlDataConverter { } if (schemaElement == null) { - - //QName type = null; if (elementStack.isEmpty()) { schemaElement = new TopLevelElement(); s.getSimpleTypeOrComplexTypeOrGroup().add(schemaElement); } else { - - -// if (sameNameSpace) { -// localElement = new LocalElement(); -// schemaElement = localElement; -// //type = new QName(elementName); -// -// } else { - schemaElement = new TopLevelElement(); - s.getSimpleTypeOrComplexTypeOrGroup().add(schemaElement); - //type = new QName(SchemaConversionBase.SCHEMA_NS,"element"); - - -// } + schemaElement = new TopLevelElement(); + s.getSimpleTypeOrComplexTypeOrGroup().add(schemaElement); } schemaElement.setName(elementName); elementNsMap.put(schemaElement, currentNS); @@ -250,7 +233,7 @@ public class XmlDataConverter { Attribute attribute = attributeIterator.next(); if ("http://www.w3.org/XML/1998/namespace".equals(attribute.getName().getNamespaceURI())) continue; - addAttribute(attribute, complexType, parseElement.getNamespaceURI(attribute.getName().getPrefix())); + addAttribute(attribute, complexType, currentNS); } } else { @@ -273,7 +256,7 @@ public class XmlDataConverter { continue; org.w3._2001.xmlschema.Attribute schemaAttribute = currentAttributes.get(attribute.getName().getLocalPart()); if (schemaAttribute == null) { - addAttribute(attribute, complexType, parseElement.getNamespaceURI(attribute.getName().getPrefix())); + addAttribute(attribute, complexType, currentNS); } else { QName newType = getType(attribute.getValue()); updateAttributeType(schemaAttribute, newType); @@ -287,9 +270,9 @@ public class XmlDataConverter { // System.out.println("End " + element.getName()); elementStack.pop(); } else if (event.isAttribute()) { - System.out.println(event); + } else if (event.isStartDocument()) { - System.out.println(event); + } else if (event.isEndDocument()) { } else if (event.isEntityReference()) { @@ -299,7 +282,7 @@ public class XmlDataConverter { // if (!characters.isWhiteSpace()) // System.out.println(characters.getData()); } else if (event.isNamespace()) { - System.out.println(event); + } } } @@ -352,8 +335,6 @@ public class XmlDataConverter { } private void addAttribute(Attribute attribute, ComplexType complexType, String currentNS) { - if (attribute.getName().getLocalPart().equals("Panel.ZIndex")) - System.out.println(); if (attribute.getName().getNamespaceURI().length() == 0 || attribute.getName().getNamespaceURI().equals(currentNS)) { org.w3._2001.xmlschema.Attribute schemaAttribute = new org.w3._2001.xmlschema.Attribute(); schemaAttribute.setName(attribute.getName().getLocalPart()); @@ -406,8 +387,6 @@ public class XmlDataConverter { } } } - if ("Panel.ZIndex".equals(schemaAttribute.getName())) - System.out.println(); complexType.getAttributeOrAttributeGroup().add(schemaAttribute); } diff --git a/org.simantics.xml.sax/src/org/simantics/xml/sax/ExporterGenerator.java b/org.simantics.xml.sax/src/org/simantics/xml/sax/ExporterGenerator.java index 5294e91..e3d0add 100644 --- a/org.simantics.xml.sax/src/org/simantics/xml/sax/ExporterGenerator.java +++ b/org.simantics.xml.sax/src/org/simantics/xml/sax/ExporterGenerator.java @@ -64,7 +64,7 @@ public class ExporterGenerator extends JavaGenerator{ mainWriter.println(); mainWriter.println(" public " + name + importerClassPostfix+"(Session session, File file, Resource root) throws DatabaseException {"); mainWriter.println(" super(session, file, root);"); - mainWriter.println(" setXmlWriter(new "+name + parserClassPostfix+"(session));"); + mainWriter.println(" setXmlWriter(new "+name + parserClassPostfix+"(session).resolveDependencies(session));"); mainWriter.println(" }"); mainWriter.println(); mainWriter.println("}"); @@ -100,6 +100,39 @@ public class ExporterGenerator extends JavaGenerator{ mainWriter.println(" }"); mainWriter.println(" });"); mainWriter.println(" }"); + + mainWriter.println(); + if (converter.getSubConverters().size() > 0) { + mainWriter.println(" public void addDependencies(org.simantics.db.Session session, java.util.Map map) throws DatabaseException {"); + for (SchemaConverter sc : converter.getSubConverters()) { + String s = sc.className; + if (s.endsWith("Ontology")) + s = s.substring(0,s.length()-"Ontology".length()); + s +="Writer"; + mainWriter.println(" {"); + mainWriter.println(" XMLWriter parser = new "+s+"(session);"); + mainWriter.println(" if (!map.containsKey(parser.getSchemaURI())) {"); + mainWriter.println(" map.put(parser.getSchemaURI(), parser);"); + mainWriter.println(" parser.addDependencies(session,map);"); + mainWriter.println(" } else {"); + mainWriter.println(" parser = map.get(parser.getSchemaURI());"); + mainWriter.println(" }"); + mainWriter.println(" add(parser);"); + mainWriter.println(" }"); + } + mainWriter.println(" }"); + + mainWriter.println(" public XMLWriter resolveDependencies(org.simantics.db.Session session) throws DatabaseException {"); + mainWriter.println(" super.resolveDependencies(session);"); + for (SchemaConverter sc : converter.getSubConverters()) { + String s = sc.schemaNs; + mainWriter.println(" if (!nsPrefixes.containsKey(\""+s+"\")) {"); + mainWriter.println(" nsPrefixes.put(\""+s+"\", \"ns\"+nsPrefixes.size());"); + mainWriter.println(" }"); + } + mainWriter.println(" return this;"); + mainWriter.println(" }"); + } mainWriter.println("}"); mainWriter.println(); @@ -280,8 +313,6 @@ public class ExporterGenerator extends JavaGenerator{ protected void createReferenceIndicator(SchemaObject parent, RefType referenceType, String refName, String objectName, String primaryClassName, String secondaryClassName, boolean useElementList, boolean useOriginalList) { FileWriter fw = getWriter(parent); - if ("TextOrField".equals(refName)) - System.out.println(); if (referenceType == RefType.Type) { // create internal class for handling the element and child attachment secondaryClassName = getName(parent) +"_" +objectName; @@ -430,6 +461,7 @@ public class ExporterGenerator extends JavaGenerator{ String relationName; String attrName; + String ns = null; if (name != null) { attrName = name; relationName = ontShort+"has"+base.getName(attribute); @@ -444,6 +476,8 @@ public class ExporterGenerator extends JavaGenerator{ if (referred != null) { primitiveType = referred.getType(); simpleType = referred.getSimpleType(); + if (ref.getNamespaceURI() != null && !ref.getNamespaceURI().equals(this.converter.schemaNs)) + ns = ref.getNamespaceURI(); } } else { @@ -460,7 +494,10 @@ public class ExporterGenerator extends JavaGenerator{ TypeEntry binding = base.getTypeEntry(primitiveType); if (binding != null) { - writeAttribute(fw, attrName, relationName, binding, isReference); + if (ns != null) + writeAttribute(fw, ns, attrName, relationName, binding, isReference); + else + writeAttribute(fw, attrName, relationName, binding, isReference); return; } else { if (simpleType == null) { @@ -470,6 +507,7 @@ public class ExporterGenerator extends JavaGenerator{ } } } + if (simpleType != null) { org.w3._2001.xmlschema.List list = simpleType.getList(); if (list != null) { @@ -484,7 +522,10 @@ public class ExporterGenerator extends JavaGenerator{ //String binding = getBindingFromPrimitiveType(base); TypeEntry binding = this.base.getTypeEntry(base); - writeAttribute(fw, attrName, relationName, binding, isReference); + if (base.getNamespaceURI() != null) + writeAttribute(fw, base.getNamespaceURI(), attrName, relationName, binding, isReference); + else + writeAttribute(fw, attrName, relationName, binding, isReference); } } else { // TODO : using default String attribute should be configured with rules. @@ -506,6 +547,17 @@ public class ExporterGenerator extends JavaGenerator{ fw.writer.println(" }"); } + private void writeAttribute(FileWriter fw, String ns, String attrName, String relationName, TypeEntry binding, boolean isReference) { + fw.writer.println(" {"); + fw.writer.println(" if (attribute.getPredicate().equals("+relationName+")) {"); + fw.writer.println(" writer.writeAttribute(\""+ns+"\",\""+attrName+"\", " + binding.getToString("graph.getValue(attribute.getObject(),"+binding.binding+")")+");"); + // fw.writer.println(" graph.claimLiteral(element.getData(),"+relationName+","+getValueGetterMethod(binding,"a")+", "+binding.binding+");"); + // if (isReference) + // fw.writer.println(" idProviderValue = a.getValue();"); + fw.writer.println(" }"); + fw.writer.println(" }"); + } + @Override public void handleAttributes(SchemaObject simpleTypeObj) { SchemaObject parent = simpleTypeObj.getParent(); diff --git a/org.simantics.xml.sax/src/org/simantics/xml/sax/ImporterGenerator.java b/org.simantics.xml.sax/src/org/simantics/xml/sax/ImporterGenerator.java index 4b0d1b5..9270c8f 100644 --- a/org.simantics.xml.sax/src/org/simantics/xml/sax/ImporterGenerator.java +++ b/org.simantics.xml.sax/src/org/simantics/xml/sax/ImporterGenerator.java @@ -257,8 +257,8 @@ public class ImporterGenerator extends JavaGenerator{ @Override public void createReferenceIndicator(SchemaObject parent, RefType referenceType, String refName, String objectName, String primaryClassName, String secondaryClassName, boolean useElementList, boolean useOriginalList) { - if (refName == null) - System.out.println(); +// if (refName == null) +// System.out.println(); FileWriter fw = getWriter(parent); if (referenceType == RefType.Type) { // create internal class for handling the element and child attachment @@ -339,8 +339,8 @@ public class ImporterGenerator extends JavaGenerator{ @Override protected void createElementIndicator(SchemaObject parent, boolean useElementList, String refName, String className, boolean useOriginalList) { - if (refName == null) - System.out.println(); +// if (refName == null) +// System.out.println(); FileWriter fw = getWriter(parent); //if (!reference) fw.writer.println(" addParser(\""+ refName +"\", "+className+".class);"); @@ -522,8 +522,6 @@ public class ImporterGenerator extends JavaGenerator{ } } //dd - if(true) - System.out.println(); fw.writer.println(commentTag+" End of AttributeGroup " + group.getName()); } @@ -576,12 +574,7 @@ public class ImporterGenerator extends JavaGenerator{ } - - - - - - + IDProvider provider; @Override public void handleElement(SchemaObject elementObj) { diff --git a/org.simantics.xml.sax/src/org/simantics/xml/sax/SchemaConversionBase.java b/org.simantics.xml.sax/src/org/simantics/xml/sax/SchemaConversionBase.java index 049b087..51707cb 100644 --- a/org.simantics.xml.sax/src/org/simantics/xml/sax/SchemaConversionBase.java +++ b/org.simantics.xml.sax/src/org/simantics/xml/sax/SchemaConversionBase.java @@ -204,10 +204,12 @@ public final class SchemaConversionBase { private Map complexTypeName = new HashMap<>(); private Map simpleTypeName = new HashMap<>(); private Map modelGroupName = new HashMap<>(); + private Map attrName = new HashMap<>(); private Map elements = new HashMap<>(); private Map complexTypes = new HashMap<>(); private Map simpleTypes = new HashMap<>(); private Map modelGroups = new HashMap<>(); + private Map attributes = new HashMap<>(); private SchemaObject _getWithName(QName name) { SchemaObject obj = elementName.get(name.getLocalPart()); @@ -215,6 +217,8 @@ public final class SchemaConversionBase { obj = complexTypeName.get(name.getLocalPart()); if (obj == null) obj = simpleTypeName.get(name.getLocalPart()); + if (obj == null) + obj = attrName.get(name.getLocalPart()); return obj; } @@ -373,7 +377,9 @@ public final class SchemaConversionBase { SchemaObject obj = new SchemaObject(this,simpleType); stack.push(obj); } else if (attrs instanceof Attribute) { - // Attributes are not cached + Attribute attribute = (Attribute)attrs; + SchemaObject obj = new SchemaObject(this, attribute); + stack.push(obj); } else if (attrs instanceof AttributeGroup) { // Attribute groups are not cached } else if (attrs instanceof NamedGroup) { @@ -466,6 +472,12 @@ public final class SchemaConversionBase { modelGroups.put(e, object); break; } + case ATTRIBUTE: { + Attribute e = object.getAttribute(); + attrName.put(e.getName(), object); + attributes.put(e, object); + break; + } } } // while } @@ -730,13 +742,30 @@ public final class SchemaConversionBase { return type; } + private SchemaObject _getAttribute(QName name) { + return attrName.get(name.getLocalPart()); + } + protected Attribute getRefAttribute(QName ref) { - for (OpenAttrs attrs : schema.getSimpleTypeOrComplexTypeOrGroup()) { - if (attrs instanceof TopLevelAttribute) { - TopLevelAttribute attribute = (TopLevelAttribute)attrs; - if (attribute.getName().equals(ref.getLocalPart())) - return attribute; - } +// for (OpenAttrs attrs : schema.getSimpleTypeOrComplexTypeOrGroup()) { +// if (attrs instanceof TopLevelAttribute) { +// TopLevelAttribute attribute = (TopLevelAttribute)attrs; +// if (attribute.getName().equals(ref.getLocalPart())) +// return attribute; +// } +// } + SchemaObject obj = _getAttribute(ref); + if (obj != null) + return obj.getAttribute(); + if (ref.getNamespaceURI() != null) { + for (SchemaConverter sc : converter.getConverter(ref.getNamespaceURI())) { + if (sc.base != null) { + obj = sc.base._getAttribute(ref); + if (obj != null) { + return obj.getAttribute(); + } + } + } } return null; } diff --git a/org.simantics.xml.sax/src/org/simantics/xml/sax/SchemaObject.java b/org.simantics.xml.sax/src/org/simantics/xml/sax/SchemaObject.java index 53f9da9..cae9792 100644 --- a/org.simantics.xml.sax/src/org/simantics/xml/sax/SchemaObject.java +++ b/org.simantics.xml.sax/src/org/simantics/xml/sax/SchemaObject.java @@ -1,6 +1,7 @@ package org.simantics.xml.sax; import org.simantics.xml.sax.configuration.Rename; +import org.w3._2001.xmlschema.Attribute; import org.w3._2001.xmlschema.AttributeGroup; import org.w3._2001.xmlschema.AttributeGroupRef; import org.w3._2001.xmlschema.ComplexType; @@ -11,7 +12,7 @@ import org.w3._2001.xmlschema.OpenAttrs; import org.w3._2001.xmlschema.SimpleType; public class SchemaObject { - enum ObjectType{ELEMENT,COMPLEX_TYPE,SIMPLE_TYPE,ATTRIBUTE_GROUP,MODEL_GROUP}; + enum ObjectType{ELEMENT,COMPLEX_TYPE,SIMPLE_TYPE,ATTRIBUTE_GROUP,MODEL_GROUP,ATTRIBUTE}; private SchemaConversionBase sc; private String name; @@ -41,6 +42,10 @@ public class SchemaObject { this(sc,null, namedGroup); } + public SchemaObject(SchemaConversionBase sc, Attribute attribute) { + this(sc,null, attribute); + } + public SchemaObject(SchemaConversionBase sc,SchemaObject parent, Element element) { this.parent = parent; this.obj = element; @@ -82,6 +87,14 @@ public class SchemaObject { _init(); } + public SchemaObject(SchemaConversionBase sc,SchemaObject parent, Attribute attribute) { + this.parent = parent; + this.obj = attribute; + this.type = ObjectType.ATTRIBUTE; + this.sc = sc; + _init(); + } + private void _init() { name = _getName(); if (name != null) @@ -118,6 +131,12 @@ public class SchemaObject { return (NamedGroup)obj; } + public Attribute getAttribute() { + if (type != ObjectType.ATTRIBUTE) + return null; + return (Attribute)obj; + } + public SchemaObject getParent() { return parent; } @@ -153,6 +172,8 @@ public class SchemaObject { return ((Element)obj).getName(); case SIMPLE_TYPE: return ((SimpleType)obj).getName(); + case ATTRIBUTE: + return ((Attribute)obj).getName(); } throw new RuntimeException("Unknown object type " + type); } -- 2.47.1