\r
import java.lang.reflect.Constructor;\r
import java.lang.reflect.InvocationTargetException;\r
-import java.util.Collection;\r
import java.util.HashMap;\r
+import java.util.HashSet;\r
+import java.util.LinkedHashSet;\r
import java.util.List;\r
import java.util.Map;\r
import java.util.Set;\r
import org.simantics.db.common.utils.ListUtils;\r
import org.simantics.db.common.utils.NameUtils;\r
import org.simantics.db.exception.DatabaseException;\r
+import org.simantics.layer0.Layer0;\r
import org.simantics.message.ILogger;\r
import org.simantics.xml.sax.ontology.XMLResource;\r
\r
public class XMLWriter {\r
\r
private ReadGraph graph;\r
- private Map<String, XMLWriter> subWriters = new HashMap<String, XMLWriter>();\r
+ private Map<Resource, XMLWriter> subWriters = new HashMap<Resource, XMLWriter>();\r
private Map<Class<? extends XMLElementWriter>, XMLElementWriter> namedWriters = new HashMap<Class<? extends XMLElementWriter>, XMLElementWriter>();\r
private Map<Resource,XMLElementWriter> writers = new HashMap<>();\r
private String schemaURI;\r
+ private String ontologyURI;\r
+ private Resource ontology;\r
\r
private ILogger logger;\r
\r
return graph;\r
}\r
\r
- public void setGraph(ReadGraph graph) {\r
+ public void setGraph(ReadGraph graph) throws DatabaseException {\r
this.graph = graph;\r
for (XMLWriter p : subWriters.values())\r
p.setGraph(graph);\r
+ if (ontologyURI != null)\r
+ this.ontology = graph.getResource(ontologyURI);\r
}\r
\r
public String getSchemaURI() {\r
this.schemaURI = schemaURI;\r
}\r
\r
+ public String getOntologyURI() {\r
+ return ontologyURI;\r
+ }\r
+ \r
+ public void setOntologyURI(String ontologyURI) {\r
+ this.ontologyURI = ontologyURI;\r
+ }\r
+ \r
+ public Resource getOntology() {\r
+ return ontology;\r
+ }\r
+ \r
public void add(XMLElementWriter writer) throws DatabaseException {\r
Resource type = writer.getType(graph);\r
if (type != null)\r
}\r
\r
public void add(XMLWriter writer) {\r
- subWriters.put(writer.getSchemaURI(), writer);\r
+ subWriters.put(writer.getOntology(), writer);\r
}\r
\r
public void write(Resource root, XMLStreamWriter writer) throws DatabaseException, XMLStreamException {\r
\r
XMLElementWriter elementWriter = instance.writer;\r
elementWriter.start(graph, instance, writer);\r
+ if (instance.parent == null) {\r
+ if(getSchemaURI() != null) {\r
+ writer.writeDefaultNamespace(getSchemaURI());\r
+ }\r
+ }\r
elementWriter.attributes(graph, instance, graph.getStatements(instance.instance, XML.hasAttribute), writer);\r
if (graph.hasValue(instance.instance))\r
elementWriter.characters(graph, instance, writer);\r
// get all child elements\r
- Collection<Statement> childElements = graph.getStatements(instance.instance, XML.hasElement);\r
+ Set<Statement> childElements = new HashSet<>();\r
+ childElements.addAll(graph.getStatements(instance.instance, XML.hasElement));\r
+ childElements.addAll(graph.getStatements(instance.instance, XML.hasComplexType));\r
// load elements, assign writers\r
Map<Resource,WriterElement> elementMap = new HashMap<>();\r
for (Statement s : childElements) {\r
loadElement(c);\r
elementMap.put(s.getObject(), c);\r
}\r
- List<Resource> sorted = elementWriter.children(graph, instance, writer);\r
- \r
+ LinkedHashSet<Resource> sorted = new LinkedHashSet<>();\r
+ if (graph.hasStatement(instance.instance, XML.hasOriginalElementList)) {\r
+ Resource originalList = graph.getSingleObject(instance.instance, XML.hasOriginalElementList);\r
+ List<Resource> l = ListUtils.toList(graph, originalList);\r
+ sorted.addAll(l);\r
+ }\r
+ elementWriter.children(graph, instance, sorted);\r
+ Set<Resource> processed = new HashSet<>();\r
for (Resource r : sorted) {\r
+ if (processed.contains(r)) // badly generated writer could report elements several times. \r
+ continue;\r
WriterElement child = elementMap.get(r);\r
+ if (child == null)\r
+ throw new DatabaseException("Trying to export unregonized resource " +NameUtils.getSafeName(graph, r) + " " + r);\r
write(child, writer);\r
+ processed.add(r);\r
}\r
//write the rest of the elements (in random order) \r
for (Statement stm : childElements) {\r
- if (sorted.contains(stm.getObject()))\r
+ if (processed.contains(stm.getObject()))\r
continue;\r
WriterElement child = elementMap.get(stm.getObject());\r
+ if (child == null)\r
+ throw new DatabaseException("Trying to export unregonized resource " +NameUtils.getSafeName(graph, stm.getObject()) + " " + stm.getObject());\r
write(child, writer);\r
}\r
\r
\r
}\r
\r
-// public void write(Resource root, XMLStreamWriter writer) throws DatabaseException, XMLStreamException {\r
-// XMLResource XML = XMLResource.getInstance(graph);\r
-// \r
-// Deque<Element> stack = new ArrayDeque<>();\r
-// Element rootElement = new Element(root);\r
-// loadElement(rootElement);\r
-// stack.push(rootElement);\r
-// while (!stack.isEmpty()) {\r
-// \r
-// Element instance = stack.pop();\r
-// XMLElementWriter elementWriter = instance.writer;\r
-// elementWriter.start(graph, instance.instance, writer);\r
-// elementWriter.attributes(graph, graph.getStatements(instance.instance, XML.hasAttribute), writer);\r
-// // get all child elements\r
-// Collection<Statement> childElements = graph.getStatements(instance.instance, XML.hasElement);\r
-// // get original element order, if available\r
-// Resource originalElementList = graph.getPossibleObject(instance.instance, XML.hasOriginalElementList);\r
-// List<Resource> originalList = null;\r
-// if (originalElementList != null) {\r
-// originalList = ListUtils.toList(graph, originalElementList);\r
-// }\r
-// if (originalList != null) {\r
-// // check for elements that are missing form the original list (should be empty). \r
-// for (Statement stm : childElements) {\r
-// if (originalList.contains(stm.getObject()))\r
-// continue;\r
-// Element child = new Element(instance,stm.getObject());\r
-// loadElement(child);\r
-// stack.push(child);\r
-// }\r
-// // process the list in reverse order so that the stack processing processes the items in correct order.\r
-// for (int i = originalList.size()-1; i >= 0; i--) {\r
-// Resource r = originalList.get(i);\r
-// Element child = new Element(instance, r);\r
-// loadElement(child);\r
-// stack.push(child);\r
-// }\r
-// } else {\r
-// for (Statement stm : childElements) {\r
-// Element child = new Element(instance, stm.getObject());\r
-// loadElement(child);\r
-// stack.push(child);\r
-// }\r
-// }\r
-// }\r
-// }\r
- \r
private void loadElement(WriterElement child) throws DatabaseException {\r
XMLElementWriter childWriter = null;\r
if (child.parent != null && child.parent.writer instanceof XMLElementNamedChildWriter) {\r
childWriter = this.writers.get(childWriterClass);\r
if (childWriter == null) {\r
try {\r
- Constructor<? extends XMLElementWriter> c = childWriterClass.getConstructor(ReadGraph.class);\r
+ Constructor<? extends XMLElementWriter> c = null;\r
+ try {\r
+ c = childWriterClass.getConstructor(ReadGraph.class);\r
+ childWriter = c.newInstance(graph);\r
+ } catch (NoSuchMethodException e) {\r
+ c = childWriterClass.getConstructor();\r
+ childWriter = c.newInstance();\r
+ }\r
//childWriter = childWriterClass.newInstance();\r
- childWriter = c.newInstance(graph);\r
+ \r
namedWriters.put(childWriterClass, childWriter);\r
} catch (IllegalAccessException|InstantiationException|NoSuchMethodException|SecurityException|InvocationTargetException e) {\r
String err = "Error processing " + childWriterClass.getName() + " : element writers must have accessible constructor with ReadGraph parameter";\r
- logger.log(new Status(IStatus.ERROR, XMLParser.PLUGIN_ID, err));\r
+ logger.log(new Status(IStatus.ERROR, XMLParser.PLUGIN_ID, err, e));\r
} \r
}\r
}\r
childWriter = writers.get(type);\r
}\r
if (childWriter == null) {\r
- throw new DatabaseException("Cannot locate writer for " + NameUtils.getSafeName(graph, child.instance) + ", " + child.instance);\r
+ Resource type = graph.getSingleType(child.instance);\r
+ Resource ontology = getOntology(type);\r
+ if (ontology != null) {\r
+ XMLWriter xmlWriter = subWriters.get(ontology);\r
+ if (xmlWriter != null) {\r
+ childWriter = xmlWriter.writers.get(type);\r
+ }\r
+ }\r
+ if (childWriter == null)\r
+ throw new DatabaseException("Cannot locate writer for " + NameUtils.getSafeName(graph, child.instance) + ", " + child.instance);\r
}\r
child.writer = childWriter;\r
\r
}\r
+ \r
+ private Resource getOntology(Resource type) throws DatabaseException {\r
+ Layer0 L0 = Layer0.getInstance(graph);\r
+ Resource r = type;\r
+ while (true) {\r
+ r = graph.getPossibleObject(r, L0.PartOf);\r
+ if (r != null && graph.isInstanceOf(r, L0.Ontology))\r
+ break;\r
+ }\r
+ return r;\r
+ }\r
\r
}\r