--- /dev/null
+package org.simantics.interop.xmlio;\r
+\r
+import java.io.BufferedReader;\r
+import java.io.File;\r
+import java.io.FileReader;\r
+import java.io.Reader;\r
+import java.io.Serializable;\r
+import java.util.ArrayList;\r
+import java.util.HashMap;\r
+import java.util.List;\r
+import java.util.Map;\r
+import java.util.Stack;\r
+\r
+import javax.xml.parsers.SAXParser;\r
+import javax.xml.parsers.SAXParserFactory;\r
+\r
+import org.simantics.db.ReadGraph;\r
+import org.simantics.db.Resource;\r
+import org.simantics.db.Session;\r
+import org.simantics.db.WriteGraph;\r
+import org.simantics.db.common.request.DelayedWriteRequest;\r
+import org.simantics.db.common.request.WriteRequest;\r
+import org.simantics.db.exception.DatabaseException;\r
+import org.simantics.db.layer0.util.SessionGarbageCollection;\r
+import org.simantics.layer0.Layer0;\r
+import org.xml.sax.Attributes;\r
+import org.xml.sax.InputSource;\r
+import org.xml.sax.SAXException;\r
+import org.xml.sax.XMLReader;\r
+import org.xml.sax.helpers.DefaultHandler;\r
+\r
+\r
+\r
+public class LoadXML {\r
+\r
+ private Session session;\r
+ private Resource resultRoot;\r
+ \r
+ private File file;\r
+ \r
+ private Map<Integer,Resource> idMap = new HashMap<Integer, Resource>();\r
+ \r
+ //private Map<String,Resource> uriMap = new HashMap<String, Resource>();\r
+ \r
+ private WriteGraph graph;\r
+ private Layer0 l0;\r
+ private LoadRule rule;\r
+ \r
+ private int resources;\r
+ private int statements;\r
+ \r
+ public LoadXML(Session session, File file) {\r
+ this.session = session;\r
+ this.file = file;\r
+ this.rule = new DefaultLoadRule();\r
+ }\r
+ \r
+ public void setRule(LoadRule rule) {\r
+ this.rule = rule;\r
+ }\r
+ \r
+ public void load(final Resource subj, final Resource pred) throws Exception {\r
+ resources = 0;\r
+ statements = 0;\r
+ // TODO : switch to Delayed if possible\r
+ // Delayed Write Graph in 1.6 does not seem to support converting virtual Resources to real Resources!\r
+ \r
+ session.syncRequest(new DelayedWriteRequest() {\r
+ //session.syncRequest(new WriteRequest() {\r
+ \r
+ @Override\r
+ public void perform(WriteGraph graph) throws DatabaseException {\r
+ LoadXML.this.graph = graph;\r
+ l0 = Layer0.getInstance(graph);\r
+ try {\r
+ XMLParser parser = new XMLParser();\r
+ parser.parse(file.getAbsolutePath());\r
+ } catch (Exception e) {\r
+ throw new DatabaseException(e);\r
+ } finally {\r
+ resultRoot = idMap.get(0);\r
+ graph.claim(subj, pred, resultRoot);\r
+ idMap.clear();\r
+ }\r
+ }\r
+ });\r
+ \r
+ System.out.println("Imported " + statements + " Statements, " + resources + " Resources.");\r
+ }\r
+ \r
+ \r
+// public Resource getResult() {\r
+// return resultRoot;\r
+// }\r
+ \r
+ protected Resource getResource(ReadGraph graph, String uri) throws DatabaseException {\r
+ return rule.getResource(graph, uri);\r
+ }\r
+ \r
+ protected Object createValue(ReadGraph graph, List<String> value, List<String> types) throws DatabaseException {\r
+ return rule.createValue(graph, value, types);\r
+ }\r
+ \r
+ protected void initializeWithBundles(ReadGraph graph, List<Bundle> bundles) throws DatabaseException {\r
+ rule.initializeWithBundles(graph, bundles);\r
+ }\r
+ \r
+ \r
+ public class XMLParser extends DefaultHandler implements Serializable {\r
+\r
+ private static final long serialVersionUID = -4995836637014958966L;\r
+ \r
+ private Stack<Element> current = new Stack<Element>();\r
+ \r
+ private void loadElement(Element element) throws SAXException{\r
+ String name = element.qName;\r
+ if ("graphexport".equals(name))\r
+ return;\r
+ if ("graphbundles".equals(name)) {\r
+ element.setData(new ArrayList<Bundle>());\r
+ return;\r
+ }\r
+ if ("bundle".equals(name))\r
+ return;\r
+ if ("resource".equals(name)) {\r
+ element.setData(new Res());\r
+ return;\r
+ }\r
+ if ("type".equals(name)) {\r
+ return;\r
+ }\r
+ if ("statement".equals(name))\r
+ return;\r
+ \r
+ }\r
+ \r
+ private void handleElement(Stack<Element> parents, Element element) throws SAXException{\r
+ try {\r
+ String elementName = element.qName;\r
+ if ("graphexport".equals(elementName))\r
+ return;\r
+ if ("graphbundles".equals(elementName)) {\r
+ List<Bundle> list = (List<Bundle>)element.getData();\r
+ initializeWithBundles(graph, list);\r
+ element.setData(null);\r
+ return;\r
+ }\r
+ if ("bundle".equals(elementName)) {\r
+ List<Bundle> list = (List<Bundle>)parents.peek().getData();\r
+ String name = null;\r
+ String versionId = null;\r
+ for (Attribute a : element.getAttributes()) {\r
+ if ("name".equals(a.qName))\r
+ name = a.value;\r
+ if ("versionid".equals(a.qName))\r
+ versionId = a.value;\r
+ } \r
+ list.add(new Bundle(name,versionId));\r
+ return;\r
+ }\r
+ if ("resource".equals(elementName)) {\r
+ Res res = (Res)element.getData();\r
+ boolean rel = false;\r
+ String uri = null;\r
+ int id = -1;\r
+ Resource r = null;\r
+ for (Attribute a : element.getAttributes()) {\r
+ if ("id".equals(a.qName))\r
+ id = Integer.parseInt(a.value);\r
+ if ("rel".equals(a.qName))\r
+ rel = "true".equals(a.value);\r
+ if ("uri".equals(a.qName))\r
+ uri = a.value;\r
+ } \r
+ if (rel) {\r
+ r = getResource(graph, uri);\r
+ } else {\r
+ \r
+ r = graph.newResource();\r
+ for (String typeUri : res.types) {\r
+ Resource type =getResource(graph, typeUri);\r
+ graph.claim(r, l0.InstanceOf, type);\r
+ }\r
+ \r
+ if (res.values.size() > 0 ) {\r
+ Object valObj = createValue(graph, res.values, res.types);\r
+ graph.claimValue(r, valObj);\r
+ }\r
+ }\r
+ if (id == -1)\r
+ throw new SAXException("Resource id missing");\r
+ idMap.put(id, r);\r
+ \r
+ res.types.clear();\r
+ res.values.clear();\r
+ element.setData(null);\r
+ resources++;\r
+ return;\r
+ }\r
+ if ("type".equals(elementName)) {\r
+ Element parent = parents.peek();\r
+ Res res = (Res)parent.getData();\r
+ String uri = null;\r
+ for (Attribute a : element.getAttributes()) {\r
+ if ("uri".equals(a.qName))\r
+ uri = a.value;\r
+ } \r
+ if (uri != null)\r
+ res.types.add(uri);\r
+ \r
+ return;\r
+ }\r
+ if ("value".equals(elementName)) {\r
+ Element parent = parents.peek();\r
+ Res res = (Res)parent.getData();\r
+ String value = null;\r
+ for (Attribute a : element.getAttributes()) {\r
+ if ("value".equals(a.qName))\r
+ value = a.value;\r
+ } \r
+ if (value != null)\r
+ res.values.add(value);\r
+ \r
+ return;\r
+ }\r
+ if ("statement".equals(elementName)) {\r
+ int subjId = -1;\r
+ int predId = -1;\r
+ int objId = -1;\r
+ for (Attribute a : element.getAttributes()) {\r
+ if ("subject".equals(a.qName))\r
+ subjId = Integer.parseInt(a.value);\r
+ if ("predicate".equals(a.qName))\r
+ predId = Integer.parseInt(a.value);\r
+ if ("object".equals(a.qName))\r
+ objId = Integer.parseInt(a.value);\r
+ } \r
+ \r
+ graph.claim(idMap.get(subjId), idMap.get(predId), idMap.get(objId));\r
+ statements++;\r
+ if (statements % 10000 == 0) {\r
+ System.out.println("Imported " + statements + " Statements, " + resources + " Resources..");\r
+ //SessionGarbageCollection.gc(graph, 0, -1);\r
+ }\r
+ return;\r
+ }\r
+ \r
+ } catch (DatabaseException e) {\r
+ throw new SAXException(e);\r
+ }\r
+ }\r
+ \r
+ public void done() {\r
+ \r
+ }\r
+ \r
+ public void parse(String filename) throws Exception {\r
+ SAXParserFactory spf = SAXParserFactory.newInstance();\r
+ SAXParser saxParser = spf.newSAXParser();\r
+ \r
+ XMLReader reader = saxParser.getXMLReader();\r
+ Reader file = new BufferedReader(new FileReader(filename));\r
+ reader.setContentHandler(this);\r
+ reader.parse(new InputSource(file));\r
+ done();\r
+ }\r
+ \r
+ @Override\r
+ public void startElement(String uri, String localName, String name,\r
+ Attributes attributes) throws SAXException {\r
+ Element e = new Element(uri,localName,name,attributes);\r
+ current.push(e);\r
+ //texts.push(new String());\r
+ loadElement(e);\r
+ }\r
+ \r
+ @Override\r
+ public void endElement(String uri, String localName, String name)\r
+ throws SAXException {\r
+ Element e = null;\r
+ if (!current.empty()) {\r
+ e = current.pop();\r
+ }\r
+ if (e != null) {\r
+ handleElement(current,e);\r
+ }\r
+ }\r
+ \r
+ }\r
+ \r
+ public class Attribute {\r
+ public String localName;\r
+ public String qName;\r
+ public String uri;\r
+ public String value;\r
+ \r
+ public Attribute(String localName, String qName, String uri, String value) {\r
+ this.localName = localName;\r
+ this.qName = qName;\r
+ this.uri = uri;\r
+ this.value = value;\r
+ }\r
+ }\r
+ \r
+ public class Element implements Serializable {\r
+ private static final long serialVersionUID = -5207502156942818875L;\r
+ String uri;\r
+ String localName;\r
+ String qName;\r
+ List<Attribute> attributes = new ArrayList<Attribute>();\r
+ \r
+ public Element(String uri, String localName, String qName, Attributes attributes) {\r
+ this.uri = uri;\r
+ this.localName = localName;\r
+ this.qName = qName;\r
+ for (int i = 0; i < attributes.getLength(); i++) {\r
+ this.attributes.add(new Attribute(attributes.getLocalName(i),attributes.getQName(i),attributes.getURI(i),attributes.getValue(i)));\r
+ }\r
+ }\r
+\r
+ public String getUri() {\r
+ return uri;\r
+ }\r
+\r
+ public String getLocalName() {\r
+ return localName;\r
+ }\r
+\r
+ public String getQName() {\r
+ return qName;\r
+ }\r
+\r
+ public List<Attribute> getAttributes() {\r
+ return attributes;\r
+ }\r
+\r
+ private Object data;\r
+ \r
+ public void setData(Object data) {\r
+ this.data = data;\r
+ }\r
+ \r
+ public Object getData() {\r
+ return data;\r
+ }\r
+\r
+ }\r
+ class Res {\r
+ \r
+ List<String> types = new ArrayList<String>();\r
+ List<String> values = new ArrayList<String>();\r
+ }\r
+ \r
+ public static class Bundle {\r
+ String name;\r
+ String versionId;\r
+ public Bundle(String name, String versionId) {\r
+ super();\r
+ this.name = name;\r
+ this.versionId = versionId;\r
+ }\r
+ \r
+ public String getName() {\r
+ return name;\r
+ }\r
+ \r
+ public String getVersionId() {\r
+ return versionId;\r
+ }\r
+ }\r
+ \r
+ \r
+}\r