-package org.simantics.xml.sax.base;\r
-\r
-import java.io.BufferedInputStream;\r
-import java.io.File;\r
-import java.io.FileInputStream;\r
-import java.io.Serializable;\r
-import java.util.ArrayDeque;\r
-import java.util.ArrayList;\r
-import java.util.Deque;\r
-import java.util.HashMap;\r
-import java.util.List;\r
-import java.util.Map;\r
-\r
-import javax.xml.parsers.SAXParser;\r
-import javax.xml.parsers.SAXParserFactory;\r
-\r
-import org.eclipse.core.runtime.IStatus;\r
-import org.eclipse.core.runtime.Status;\r
-import org.simantics.db.Resource;\r
-import org.simantics.db.WriteGraph;\r
-import org.simantics.db.exception.DatabaseException;\r
-import org.simantics.message.ILogger;\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
-public class XMLParser extends DefaultHandler implements Serializable {\r
-\r
- public static String PLUGIN_ID = "org.simantics.xml.sax.base";\r
- public static String XML_NAMESPACE_REF = "xmlns";\r
- \r
- private static final long serialVersionUID = 7360740940824360338L;\r
- private static final boolean debug = false;\r
- \r
- private ILogger logger;\r
- private WriteGraph graph;\r
- private Resource root;\r
- private String schemaURI;\r
- private Deque<ParserElement> current = new ArrayDeque<ParserElement>();\r
- private Map<String, XMLElementParser> parsers = new HashMap<String, XMLElementParser>();\r
- private Map<Class<? extends XMLElementParser>, XMLElementParser> namedParsers = new HashMap<Class<? extends XMLElementParser>, XMLElementParser>();\r
- private Map<String, XMLParser> subParsers = new HashMap<String, XMLParser>();\r
- \r
- public XMLParser() {\r
- \r
- }\r
- \r
- public WriteGraph getGraph() {\r
- return graph;\r
- }\r
- \r
- public void setGraph(WriteGraph graph) {\r
- this.graph = graph;\r
- for (XMLParser p : subParsers.values())\r
- p.setGraph(graph);\r
- }\r
- \r
- public String getSchemaURI() {\r
- return schemaURI;\r
- }\r
- \r
- public void setSchemaURI(String schemaURI) {\r
- this.schemaURI = schemaURI;\r
- }\r
- \r
- public void add(XMLElementParser parser) {\r
- if (parser.getElementId() != null)\r
- parsers.put(parser.getElementId(), parser);\r
- namedParsers.put(parser.getClass(), parser);\r
- }\r
- \r
- public void add(XMLParser parser) {\r
- subParsers.put(parser.getSchemaURI(), parser);\r
- }\r
- \r
- private List<ParserElement> idReferenceElements = new ArrayList<ParserElement>();\r
- private void loadElement(Deque<ParserElement> parents, ParserElement element) throws SAXException{\r
- XMLElementParser parser = null;\r
- ParserElement parent = null;\r
- if (parents.size() > 0) {\r
- parent = parents.peek();\r
- // check for assigned subparser\r
- if (parent.getXMLParser() != null && parent.getXMLParser() != this) {\r
- element.setXMLParser(parent.getXMLParser());\r
- parent.getXMLParser().loadElement(parents, element);\r
- return;\r
- }\r
- if (parent.getElementParser() instanceof XMLElementNamedChildParser) {\r
- // use parent's named child parser if it is supported\r
- Class<? extends XMLElementParser> parserClass = ((XMLElementNamedChildParser)parent.getElementParser()).getParser(parsers,parent,element);\r
- if (parserClass != null) {\r
- parser = namedParsers.get(parserClass);\r
- if (parser == null) {\r
- try {\r
- parser = parserClass.newInstance();\r
- namedParsers.put(parserClass, parser);\r
- } catch (IllegalAccessException | InstantiationException e) {\r
- String err = "Error processing " + parserClass.getName() + " : element parsers must have accessible default constructor";\r
- logger.log(new Status(IStatus.ERROR, PLUGIN_ID, err));\r
- throw new SAXException(err, e);\r
- }\r
- }\r
- } \r
-// if (parser == null && ((XMLElementNamedChildParser)parent.getParser()).useGlobalRules())\r
-// parser = parsers.get(element.qName);\r
- } else {\r
- // otherwise use globally configured element parser\r
- parser = parsers.get(element.qName);\r
- }\r
- } else {\r
- // use globally configured element parser\r
- parser = parsers.get(element.qName);\r
- }\r
- \r
- if (parser != null) {\r
- try {\r
- \r
- element.setData(parser.create(graph, element));\r
- if (parser instanceof IDReferenceParser)\r
- idReferenceElements.add(element);\r
- element.setElementParser(parser);\r
- } catch (DatabaseException e) {\r
- throw new SAXException(e);\r
- }\r
- } else {\r
- // check for schema reference attempt to locate subparser for it.\r
- Attribute schemaRef = element.getAttribute(XML_NAMESPACE_REF);\r
- if (schemaRef != null && subParsers.containsKey(schemaRef.value)) {\r
- XMLParser subParser = subParsers.get(schemaRef.value);\r
- subParser.loadElement(parents, element);\r
- element.setXMLParser(subParser);\r
- } else {\r
- if (parent == null && parents.size() > 0)\r
- parent = parents.peek();\r
- String err = "Unknown element " + element.qName + ", parent " + (parent != null ? parent.getQName() : "None");\r
- logger.log(new Status(IStatus.ERROR, PLUGIN_ID, err));\r
- if (debug) System.err.println(err);\r
- }\r
- }\r
- }\r
- \r
- private Map<String, ParserElement> idMap = new HashMap<String, ParserElement>();\r
- \r
- private void handleElement(Deque<ParserElement> parents, ParserElement element) throws SAXException{\r
- XMLElementParser parser = element.getElementParser();\r
- if (parser != null) {\r
- try {\r
- parser.configure(graph, parents, element);\r
- if (parents.size() > 0) {\r
- ParserElement parent = parents.peek();\r
- if (parent.getElementParser() != null) {\r
- if (!parent.getElementParser().connectChild(graph, parent, element))\r
- if (!parser.connectParent(graph, parent, element)) {\r
- String err = "Did not connect element " + element.qName + ", parent " + (parent != null ? parent.getQName() : "None");\r
- logger.log(new Status(IStatus.ERROR, PLUGIN_ID, err));\r
- if (debug) System.err.println(err);\r
- }\r
- } else {\r
- String err = "Did not connect element " + element.qName + ", parent " + (parent != null ? parent.getQName() : "None") + " was not imported";\r
- logger.log(new Status(IStatus.ERROR, PLUGIN_ID, err));\r
- if (debug) System.err.println(err);\r
- }\r
- }\r
- String id = parser.getID();\r
- if (id != null) {\r
- ParserElement existing = idMap.put(id, element);\r
- if (existing != null) {\r
- // report error + use id priorities to select the kept element.\r
- boolean useExt = existing.elementParser.idPriority() > element.elementParser.idPriority();\r
- if (useExt)\r
- idMap.put(id, existing);\r
- String err = "Duplicate XML element id: " + id + " for " + element.getQName() + " and " + existing.getQName() + ", using " + (useExt ? existing.getQName() : element.getQName());\r
- logger.log(new Status(IStatus.ERROR, PLUGIN_ID, err));\r
- if (debug) System.err.println(err);\r
- }\r
- }\r
- } catch (DatabaseException e) {\r
- throw new SAXException(e);\r
- }\r
- } else {\r
- ParserElement parent = parents.peek();\r
- if (parent != null) { \r
- parser = parent.getElementParser();\r
- if (parser != null && parser instanceof UnrecognizedElementParser) {\r
- try {\r
- ((UnrecognizedElementParser)parser).configureChild(graph, parents, parent, element);\r
- } catch (DatabaseException e) {\r
- throw new SAXException(e);\r
- }\r
- }\r
- }\r
- }\r
- }\r
- \r
- private void handleCharacters(ParserElement element, String string) throws SAXException{\r
- XMLElementParser parser = element.getElementParser();\r
- if (parser != null) {\r
- try {\r
- parser.configure(graph, element, string);\r
- } catch (DatabaseException e) {\r
- logger.log(new Status(IStatus.ERROR, PLUGIN_ID, e.getMessage()));\r
- throw new SAXException(e);\r
- }\r
- }\r
- }\r
- \r
- \r
- \r
- public void done() throws SAXException{\r
- try {\r
- for (ParserElement e : idReferenceElements) {\r
- IDReferenceParser parser = (IDReferenceParser)parsers.get(e.qName);\r
- if (!parser.connectReferences(graph, e, idMap)) {\r
- String err ="Could not resolve ID references for " + e.getQName() + " " + e.getUri();\r
- logger.log(new Status(IStatus.ERROR, PLUGIN_ID, err));\r
- if (debug) System.err.println(err);\r
- }\r
- }\r
- } catch (DatabaseException e) {\r
- throw new SAXException(e);\r
- }\r
- }\r
- \r
- public Resource getRoot() {\r
- return root;\r
- }\r
- \r
- StringBuilder charactersValue;\r
- \r
- @Override\r
- public void startElement(String uri, String localName, String name, Attributes attributes) throws SAXException {\r
- ParserElement e = new ParserElement(uri,localName,name,attributes);\r
- \r
- loadElement(current,e);\r
- current.push(e);\r
- \r
- charactersValue = new StringBuilder();\r
- }\r
- \r
- @Override\r
- public void endElement(String uri, String localName, String name)\r
- throws SAXException {\r
- ParserElement e = null;\r
- if (!current.isEmpty()) {\r
- e = current.pop();\r
- }\r
- if (e != null) {\r
- handleCharacters(e, charactersValue.toString());\r
- handleElement(current,e);\r
- }\r
- if (current.isEmpty()) {\r
- root = e.getData();\r
- }\r
- \r
- charactersValue = new StringBuilder();\r
- }\r
- \r
- @Override\r
- public void characters(char[] ch, int start, int length)\r
- throws SAXException {\r
- charactersValue.append(new String(ch,start,length));\r
-// if (!current.isEmpty()) {\r
-// String s = new String(ch,start,length);\r
-// Element e = current.peek();\r
-// handleCharacters(e, s);\r
-// }\r
- \r
- }\r
- \r
- public void parse(File file, ILogger logger) throws Exception {\r
- this.logger = logger;\r
- SAXParserFactory spf = SAXParserFactory.newInstance();\r
- SAXParser saxParser = spf.newSAXParser();\r
- \r
- XMLReader reader = saxParser.getXMLReader();\r
- reader.setContentHandler(this);\r
- reader.parse(new InputSource(new BufferedInputStream(new FileInputStream(file))));\r
- done();\r
- }\r
- \r
- \r
+package org.simantics.xml.sax.base;
+
+import java.io.BufferedInputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.Serializable;
+import java.util.ArrayDeque;
+import java.util.ArrayList;
+import java.util.Deque;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import javax.xml.parsers.SAXParser;
+import javax.xml.parsers.SAXParserFactory;
+
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Status;
+import org.simantics.db.Resource;
+import org.simantics.db.WriteGraph;
+import org.simantics.db.exception.DatabaseException;
+import org.simantics.message.ILogger;
+import org.xml.sax.Attributes;
+import org.xml.sax.InputSource;
+import org.xml.sax.SAXException;
+import org.xml.sax.XMLReader;
+import org.xml.sax.helpers.DefaultHandler;
+
+public class XMLParser extends DefaultHandler implements Serializable {
+
+ public static String PLUGIN_ID = "org.simantics.xml.sax.base";
+ public static String XML_NAMESPACE_REF = "xmlns";
+
+ private static final long serialVersionUID = 7360740940824360338L;
+ private static final boolean debug = false;
+
+ private ILogger logger;
+ private WriteGraph graph;
+ private Resource root;
+ private String schemaURI;
+ private Deque<ParserElement> current = new ArrayDeque<ParserElement>();
+ private Map<String, XMLElementParser> parsers = new HashMap<String, XMLElementParser>();
+ private Map<Class<? extends XMLElementParser>, XMLElementParser> namedParsers = new HashMap<Class<? extends XMLElementParser>, XMLElementParser>();
+ private Map<String, XMLParser> subParsers = new HashMap<String, XMLParser>();
+
+ public XMLParser() {
+
+ }
+
+ public WriteGraph getGraph() {
+ return graph;
+ }
+
+ public void setGraph(WriteGraph graph) {
+ this.graph = graph;
+ for (XMLParser p : subParsers.values())
+ p.setGraph(graph);
+ }
+
+ public String getSchemaURI() {
+ return schemaURI;
+ }
+
+ public void setSchemaURI(String schemaURI) {
+ this.schemaURI = schemaURI;
+ }
+
+ public void add(XMLElementParser parser) {
+ if (parser.getElementId() != null)
+ parsers.put(parser.getElementId(), parser);
+ namedParsers.put(parser.getClass(), parser);
+ }
+
+ public void add(XMLParser parser) {
+ subParsers.put(parser.getSchemaURI(), parser);
+ }
+
+ private List<ParserElement> idReferenceElements = new ArrayList<ParserElement>();
+ private void loadElement(Deque<ParserElement> parents, ParserElement element) throws SAXException{
+ XMLElementParser parser = null;
+ ParserElement parent = null;
+ if (parents.size() > 0) {
+ parent = parents.peek();
+ // check for assigned subparser
+ if (parent.getXMLParser() != null && parent.getXMLParser() != this) {
+ element.setXMLParser(parent.getXMLParser());
+ parent.getXMLParser().loadElement(parents, element);
+ return;
+ }
+ if (parent.getElementParser() instanceof XMLElementNamedChildParser) {
+ // use parent's named child parser if it is supported
+ Class<? extends XMLElementParser> parserClass = ((XMLElementNamedChildParser)parent.getElementParser()).getParser(parsers,parent,element);
+ if (parserClass != null) {
+ parser = namedParsers.get(parserClass);
+ if (parser == null) {
+ try {
+ parser = parserClass.newInstance();
+ namedParsers.put(parserClass, parser);
+ } catch (IllegalAccessException | InstantiationException e) {
+ String err = "Error processing " + parserClass.getName() + " : element parsers must have accessible default constructor";
+ logger.log(new Status(IStatus.ERROR, PLUGIN_ID, err));
+ throw new SAXException(err, e);
+ }
+ }
+ }
+// if (parser == null && ((XMLElementNamedChildParser)parent.getParser()).useGlobalRules())
+// parser = parsers.get(element.qName);
+ } else {
+ // otherwise use globally configured element parser
+ parser = parsers.get(element.qName);
+ }
+ } else {
+ // use globally configured element parser
+ parser = parsers.get(element.qName);
+ }
+
+ if (parser != null) {
+ try {
+
+ element.setData(parser.create(graph, element));
+ if (parser instanceof IDReferenceParser)
+ idReferenceElements.add(element);
+ element.setElementParser(parser);
+ } catch (DatabaseException e) {
+ throw new SAXException(e);
+ }
+ } else {
+ // check for schema reference attempt to locate subparser for it.
+ Attribute schemaRef = element.getAttribute(XML_NAMESPACE_REF);
+ if (schemaRef != null && subParsers.containsKey(schemaRef.value)) {
+ XMLParser subParser = subParsers.get(schemaRef.value);
+ subParser.loadElement(parents, element);
+ element.setXMLParser(subParser);
+ } else {
+ if (parent == null && parents.size() > 0)
+ parent = parents.peek();
+ String err = null;
+ if (parent != null)
+ err = "Unknown element " + element.qName + ", parent " + (parent != null ? parent.getQName() : "None");
+ else {
+ err = "Unknown root element " + element.qName + ", cannot import the file";
+ throw new SAXException(err);
+ }
+
+ logger.log(new Status(IStatus.ERROR, PLUGIN_ID, err));
+ if (debug) System.err.println(err);
+ }
+ }
+ }
+
+ private Map<String, ParserElement> idMap = new HashMap<String, ParserElement>();
+
+ private void handleElement(Deque<ParserElement> parents, ParserElement element) throws SAXException{
+ XMLElementParser parser = element.getElementParser();
+ if (parser != null) {
+ try {
+ parser.configure(graph, parents, element);
+ if (parents.size() > 0) {
+ ParserElement parent = parents.peek();
+ if (parent.getElementParser() != null) {
+ if (!parent.getElementParser().connectChild(graph, parent, element))
+ if (!parser.connectParent(graph, parent, element)) {
+ String err = "Did not connect element " + element.qName + ", parent " + (parent != null ? parent.getQName() : "None");
+ logger.log(new Status(IStatus.ERROR, PLUGIN_ID, err));
+ if (debug) System.err.println(err);
+ }
+ } else {
+ String err = "Did not connect element " + element.qName + ", parent " + (parent != null ? parent.getQName() : "None") + " was not imported";
+ logger.log(new Status(IStatus.ERROR, PLUGIN_ID, err));
+ if (debug) System.err.println(err);
+ }
+ }
+ String id = parser.getID();
+ if (id != null) {
+ ParserElement existing = idMap.put(id, element);
+ if (existing != null) {
+ // report error + use id priorities to select the kept element.
+ boolean useExt = existing.elementParser.idPriority() > element.elementParser.idPriority();
+ if (useExt)
+ idMap.put(id, existing);
+ String err = "Duplicate XML element id: " + id + " for " + element.getQName() + " and " + existing.getQName() + ", using " + (useExt ? existing.getQName() : element.getQName());
+ logger.log(new Status(IStatus.ERROR, PLUGIN_ID, err));
+ if (debug) System.err.println(err);
+ }
+ }
+ } catch (DatabaseException e) {
+ throw new SAXException(e);
+ }
+ } else {
+ ParserElement parent = parents.peek();
+ if (parent != null) {
+ parser = parent.getElementParser();
+ if (parser != null && parser instanceof UnrecognizedElementParser) {
+ try {
+ ((UnrecognizedElementParser)parser).configureChild(graph, parents, parent, element);
+ } catch (DatabaseException e) {
+ throw new SAXException(e);
+ }
+ }
+ }
+ }
+ }
+
+ private void handleCharacters(ParserElement element, String string) throws SAXException{
+ XMLElementParser parser = element.getElementParser();
+ if (parser != null) {
+ try {
+ parser.configure(graph, element, string);
+ } catch (DatabaseException e) {
+ logger.log(new Status(IStatus.ERROR, PLUGIN_ID, e.getMessage()));
+ throw new SAXException(e);
+ }
+ }
+ }
+
+
+
+ public void done() throws SAXException{
+ try {
+ for (ParserElement e : idReferenceElements) {
+ IDReferenceParser parser = (IDReferenceParser)parsers.get(e.qName);
+ if (!parser.connectReferences(graph, e, idMap)) {
+ String err ="Could not resolve ID references for " + e.getQName() + " " + e.getUri();
+ logger.log(new Status(IStatus.ERROR, PLUGIN_ID, err));
+ if (debug) System.err.println(err);
+ }
+ }
+ } catch (DatabaseException e) {
+ throw new SAXException(e);
+ }
+ }
+
+ public Resource getRoot() {
+ return root;
+ }
+
+ StringBuilder charactersValue;
+
+ @Override
+ public void startElement(String uri, String localName, String name, Attributes attributes) throws SAXException {
+ ParserElement e = new ParserElement(uri,localName,name,attributes);
+
+ loadElement(current,e);
+ current.push(e);
+
+ charactersValue = new StringBuilder();
+ }
+
+ @Override
+ public void endElement(String uri, String localName, String name)
+ throws SAXException {
+ ParserElement e = null;
+ if (!current.isEmpty()) {
+ e = current.pop();
+ }
+ if (e != null) {
+ handleCharacters(e, charactersValue.toString());
+ handleElement(current,e);
+ }
+ if (current.isEmpty()) {
+ root = e.getData();
+ }
+
+ charactersValue = new StringBuilder();
+ }
+
+ @Override
+ public void characters(char[] ch, int start, int length)
+ throws SAXException {
+ charactersValue.append(new String(ch,start,length));
+// if (!current.isEmpty()) {
+// String s = new String(ch,start,length);
+// Element e = current.peek();
+// handleCharacters(e, s);
+// }
+
+ }
+
+ public void parse(File file, ILogger logger) throws Exception {
+ this.logger = logger;
+ SAXParserFactory spf = SAXParserFactory.newInstance();
+ SAXParser saxParser = spf.newSAXParser();
+
+ XMLReader reader = saxParser.getXMLReader();
+ reader.setContentHandler(this);
+ reader.parse(new InputSource(new BufferedInputStream(new FileInputStream(file))));
+ done();
+ }
+
+
}
\ No newline at end of file