]> gerrit.simantics Code Review - simantics/interop.git/commitdiff
Don't continue parsing XML file if root element is not recognised
authorMarko Luukkainen <marko.luukkainen@vtt.fi>
Thu, 21 Dec 2017 10:42:03 +0000 (12:42 +0200)
committerMarko Luukkainen <marko.luukkainen@vtt.fi>
Thu, 21 Dec 2017 10:42:03 +0000 (12:42 +0200)
org.simantics.xml.sax.base/src/org/simantics/xml/sax/base/XMLParser.java

index 9c04001477ce22e7d3e23934d21936f5c7a54d54..9689eda1f8c56b396f50ad383e60d6eccd19bab6 100644 (file)
-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