X-Git-Url: https://gerrit.simantics.org/r/gitweb?a=blobdiff_plain;f=org.simantics.xml.sax.base%2Fsrc%2Forg%2Fsimantics%2Fxml%2Fsax%2Fbase%2FXMLParser.java;h=9c04001477ce22e7d3e23934d21936f5c7a54d54;hb=04f3fb6796cd6225be090e1e1feb866ae0d03173;hp=be8fef042f4cb882d97d73aac759c5661ef63bb9;hpb=ada38ab0a1a98dcb413bef3273064da36ce2d273;p=simantics%2Finterop.git 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 be8fef0..9c04001 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 @@ -28,18 +28,41 @@ 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 Deque current = new ArrayDeque(); + private String schemaURI; + private Deque current = new ArrayDeque(); private Map parsers = new HashMap(); - private WriteGraph graph; - private Map, XMLElementParser> namedParsers = new HashMap, XMLElementParser>(); + private Map subParsers = new HashMap(); + + public XMLParser() { - public XMLParser(WriteGraph graph) { + } + + 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) { @@ -48,16 +71,25 @@ public class XMLParser extends DefaultHandler implements Serializable { namedParsers.put(parser.getClass(), parser); } + public void add(XMLParser parser) { + subParsers.put(parser.getSchemaURI(), parser); + } - private List idReferenceElements = new ArrayList(); - private void loadElement(Deque parents, Element element) throws SAXException{ + private List idReferenceElements = new ArrayList(); + private void loadElement(Deque parents, ParserElement element) throws SAXException{ XMLElementParser parser = null; - Element parent = null; + ParserElement parent = null; if (parents.size() > 0) { parent = parents.peek(); - if (parent.getParser() instanceof XMLElementNamedChildParser) { + // 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 parserClass = ((XMLElementNamedChildParser)parent.getParser()).getParser(parsers,parent,element); + Class parserClass = ((XMLElementNamedChildParser)parent.getElementParser()).getParser(parsers,parent,element); if (parserClass != null) { parser = namedParsers.get(parserClass); if (parser == null) { @@ -65,7 +97,7 @@ public class XMLParser extends DefaultHandler implements Serializable { parser = parserClass.newInstance(); namedParsers.put(parserClass, parser); } catch (IllegalAccessException | InstantiationException e) { - String err = "Element parsers must have accessible default constructor"; + 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); } @@ -88,30 +120,38 @@ public class XMLParser extends DefaultHandler implements Serializable { element.setData(parser.create(graph, element)); if (parser instanceof IDReferenceParser) idReferenceElements.add(element); - element.setParser(parser); + element.setElementParser(parser); } catch (DatabaseException e) { throw new SAXException(e); } } else { - if (parent == null && parents.size() > 0) - parent = parents.peek(); - String err = "Unknown element " + element.qName + ", parent " + (parent != null ? parent.getQName() : "None"); - logger.log(new Status(IStatus.ERROR, PLUGIN_ID, err)); - if (debug) System.err.println(err); + // 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 = "Unknown element " + element.qName + ", parent " + (parent != null ? parent.getQName() : "None"); + logger.log(new Status(IStatus.ERROR, PLUGIN_ID, err)); + if (debug) System.err.println(err); + } } } - private Map idMap = new HashMap(); + private Map idMap = new HashMap(); - private void handleElement(Deque parents, Element element) throws SAXException{ - XMLElementParser parser = element.getParser(); + private void handleElement(Deque parents, ParserElement element) throws SAXException{ + XMLElementParser parser = element.getElementParser(); if (parser != null) { try { parser.configure(graph, parents, element); if (parents.size() > 0) { - Element parent = parents.peek(); - if (parent.getParser() != null) { - if (!parent.getParser().connectChild(graph, parent, element)) + 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)); @@ -125,10 +165,10 @@ public class XMLParser extends DefaultHandler implements Serializable { } String id = parser.getID(); if (id != null) { - Element existing = idMap.put(id, element); + ParserElement existing = idMap.put(id, element); if (existing != null) { // report error + use id priorities to select the kept element. - boolean useExt = existing.parser.idPriority() > element.parser.idPriority(); + 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()); @@ -140,9 +180,9 @@ public class XMLParser extends DefaultHandler implements Serializable { throw new SAXException(e); } } else { - Element parent = parents.peek(); + ParserElement parent = parents.peek(); if (parent != null) { - parser = parent.getParser(); + parser = parent.getElementParser(); if (parser != null && parser instanceof UnrecognizedElementParser) { try { ((UnrecognizedElementParser)parser).configureChild(graph, parents, parent, element); @@ -154,8 +194,8 @@ public class XMLParser extends DefaultHandler implements Serializable { } } - private void handleCharacters(Element element, String string) throws SAXException{ - XMLElementParser parser = element.getParser(); + private void handleCharacters(ParserElement element, String string) throws SAXException{ + XMLElementParser parser = element.getElementParser(); if (parser != null) { try { parser.configure(graph, element, string); @@ -166,11 +206,11 @@ public class XMLParser extends DefaultHandler implements Serializable { } } - private static String PLUGIN_ID = "org.simantics.xml.sax.base"; + public void done() throws SAXException{ try { - for (Element e : idReferenceElements) { + 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(); @@ -187,38 +227,45 @@ public class XMLParser extends DefaultHandler implements Serializable { return root; } + StringBuilder charactersValue; + @Override public void startElement(String uri, String localName, String name, Attributes attributes) throws SAXException { - Element e = new Element(uri,localName,name,attributes); + 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 { - Element e = null; + 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 { - - if (!current.isEmpty()) { - String s = new String(ch,start,length); - Element e = current.peek(); - handleCharacters(e, s); - } + charactersValue.append(new String(ch,start,length)); +// if (!current.isEmpty()) { +// String s = new String(ch,start,length); +// Element e = current.peek(); +// handleCharacters(e, s); +// } }