]> gerrit.simantics Code Review - simantics/interop.git/blobdiff - org.simantics.xml.sax.base/src/org/simantics/xml/sax/base/ParserElement.java
Handle multi-namespace XML files.
[simantics/interop.git] / org.simantics.xml.sax.base / src / org / simantics / xml / sax / base / ParserElement.java
index 2ab58f773ae54d2d154b944bc3d0f89e8926ff17..ca4a91a39cab329739ecbc32b039767de93e14a6 100644 (file)
-package org.simantics.xml.sax.base;\r
-\r
-import java.io.Serializable;\r
-import java.util.ArrayList;\r
-import java.util.Collection;\r
-import java.util.HashMap;\r
-import java.util.List;\r
-import java.util.Map;\r
-\r
-import org.simantics.db.Resource;\r
-import org.simantics.db.WriteGraph;\r
-import org.simantics.db.common.utils.ListUtils;\r
-import org.simantics.db.exception.DatabaseException;\r
-import org.simantics.layer0.Layer0;\r
-import org.simantics.utils.datastructures.MapList;\r
-import org.xml.sax.Attributes;\r
-\r
-public class ParserElement implements Serializable {\r
-       private static final long serialVersionUID = -5207502156942818875L;\r
-       String uri;\r
-       String localName;\r
-       String qName;\r
-       Map<String, Attribute> attributes;\r
-       MapList<Resource, ParserElement> lists;\r
-\r
-       XMLElementParser elementParser;\r
-       XMLParser xmlParser;\r
-\r
-       public ParserElement(String uri, String localName, String qName, Attributes attributes) {\r
-               this.uri = uri;\r
-               this.localName = localName;\r
-               this.qName = qName;\r
-               int attrCount = attributes.getLength();\r
-               this.attributes = new HashMap<>(attrCount);\r
-               for (int i = 0; i < attrCount; i++) {\r
-                       this.attributes.put(attributes.getLocalName(i),new Attribute(attributes.getLocalName(i),attributes.getQName(i),attributes.getURI(i),attributes.getValue(i)));\r
-               }\r
-       }\r
-       \r
-       public ParserElement(String uri, String localName, String qName, Collection<Attribute> attributes) {\r
-               this.uri = uri;\r
-               this.localName = localName;\r
-               this.qName = qName;\r
-               this.attributes = new HashMap<>(attributes.size());\r
-               for (Attribute a : attributes) {\r
-                       this.attributes.put(a.localName,new Attribute(a.localName,a.qName,a.uri,a.value));\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 Collection<Attribute> getAttributes() {\r
-               return attributes.values();\r
-       }\r
-       \r
-       public Attribute getAttribute(String name) {\r
-               return attributes.get(name);\r
-       }\r
-\r
-       private Resource data;\r
-       \r
-       public void setData(Resource data) {\r
-               this.data = data;\r
-       }\r
-       \r
-       public Resource getData() {\r
-               return data;\r
-       }\r
-       \r
-       public void setElementParser(XMLElementParser parser) {\r
-               this.elementParser = parser;\r
-       }\r
-       \r
-       public XMLElementParser getElementParser() {\r
-               return elementParser;\r
-       }\r
-       \r
-       public void setXMLParser(XMLParser parser) {\r
-               this.xmlParser = parser;\r
-       }\r
-       \r
-       public XMLParser getXMLParser() {\r
-               return xmlParser;\r
-       }\r
-\r
-       public void registerListChild(Resource predicate, ParserElement child) {\r
-               if (lists == null)\r
-                       lists = new MapList<>();\r
-               lists.add(predicate, child);\r
-       }\r
-\r
-       public void createLists(WriteGraph graph) throws DatabaseException {\r
-               if (lists == null)\r
-                       return;\r
-               Layer0 L0 = Layer0.getInstance(graph);\r
-               for (Resource predicate : lists.getKeys()) {\r
-                       List<Resource> children = new ArrayList<>();\r
-                       for (ParserElement child : lists.getValues(predicate))\r
-                               children.add(child.getData());\r
-                       Resource list = ListUtils.create(graph, L0.List, L0.List_Element, null, children);\r
-                       graph.claim(getData(), predicate, list);\r
-               }\r
-       }\r
-\r
+package org.simantics.xml.sax.base;
+
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.simantics.db.Resource;
+import org.simantics.db.WriteGraph;
+import org.simantics.db.common.utils.ListUtils;
+import org.simantics.db.exception.DatabaseException;
+import org.simantics.layer0.Layer0;
+import org.simantics.utils.datastructures.MapList;
+import org.xml.sax.Attributes;
+
+public class ParserElement implements Serializable {
+       private static final long serialVersionUID = -5207502156942818875L;
+       private String uri;
+       private String localName;
+       private String qName;
+       Map<String, Attribute> attributes;
+       MapList<Resource, ParserElement> lists;
+
+       XMLElementParser elementParser;
+       XMLParser xmlParser;
+
+       Map<String,String> nsMap;
+       
+       private ParserElement parent;
+       
+       public ParserElement(String uri, String localName, String qName, Attributes attributes) {
+               this.uri = uri;
+               this.localName = localName;
+               this.qName = qName;
+               int attrCount = attributes.getLength();
+               this.attributes = new HashMap<>(attrCount);
+               for (int i = 0; i < attrCount; i++) {
+                       this.attributes.put(attributes.getLocalName(i),new Attribute(attributes.getLocalName(i),attributes.getQName(i),attributes.getURI(i),attributes.getValue(i)));
+               }
+               processNS();
+       }
+       
+       public ParserElement(String uri, String localName, String qName, Collection<Attribute> attributes) {
+               this.uri = uri;
+               this.localName = localName;
+               this.qName = qName;
+               this.attributes = new HashMap<>(attributes.size());
+               for (Attribute a : attributes) {
+                       this.attributes.put(a.localName,new Attribute(a.localName,a.qName,a.uri,a.value));
+               }
+               processNS();
+       }
+       
+       public ParserElement(ParserElement parent, String uri, String localName, String qName, Attributes attributes) {
+               this.parent = parent;
+               this.uri = uri;
+               this.localName = localName;
+               this.qName = qName;
+               int attrCount = attributes.getLength();
+               this.attributes = new HashMap<>(attrCount);
+               for (int i = 0; i < attrCount; i++) {
+                       this.attributes.put(attributes.getLocalName(i),new Attribute(attributes.getLocalName(i),attributes.getQName(i),attributes.getURI(i),attributes.getValue(i)));
+               }
+               processNS();
+       }
+       
+       public ParserElement(ParserElement parent, String uri, String localName, String qName, Collection<Attribute> attributes) {
+               this.parent = parent;
+               this.uri = uri;
+               this.localName = localName;
+               this.qName = qName;
+               this.attributes = new HashMap<>(attributes.size());
+               for (Attribute a : attributes) {
+                       this.attributes.put(a.localName,new Attribute(a.localName,a.qName,a.uri,a.value));
+               }
+               processNS();
+       }
+       
+       private void processNS() {
+               
+               nsMap = new HashMap<>();
+               for (Attribute a : attributes.values()) {
+                       if (a.localName.startsWith("xmlns")) {
+                               String ns[] = a.localName.split(":");
+                               if (ns.length == 2) {
+                                       nsMap.put(ns[1], a.value);
+                               }
+                       }
+               }
+               Map<String, Attribute> newAttrs = new HashMap<>();
+               for (Attribute a : attributes.values()) {
+                       String ns[] = a.localName.split(":");
+                       if (ns.length == 2) {
+                               if ("xmlns".equals(ns[0]))
+                                       continue;
+                               String namespace = getNS(ns[0]);
+                               if (namespace != null) {
+                                       if (newAttrs.put(ns[1], new Attribute(ns[1], a.qName, namespace, a.value)) != null)
+                                               throw new RuntimeException("XML parser internal error, overlapping attribute names " + ns[1]);
+                               } else {
+                                       throw new RuntimeException("XML parser error, namespace " + ns[0] + " for attribute " + a.localName + " not defined.");
+                               }
+                       } else {
+                               newAttrs.put(a.localName, a);
+                       }
+               }
+               attributes = newAttrs;
+               
+               String nameNs[] = qName.split(":");
+               if (nameNs.length == 2) {
+                       localName = nameNs[1];
+                       if (uri.length() == 0)
+                               uri = getNS(nameNs[0]) + "/"+localName;
+               } else if (localName.length() == 0) {
+                       localName = qName;
+               }
+       }
+       
+       public String getNS(String key) {
+               String ns = nsMap.get(key);
+               if (ns == null && parent != null)
+                       ns = parent.getNS(key);
+               return ns;
+       }
+
+       public String getUri() {
+               return uri;
+       }
+
+       public String getLocalName() {
+               return localName;
+       }
+
+       public String getQName() {
+               return qName;
+       }
+
+       public Collection<Attribute> getAttributes() {
+               return attributes.values();
+       }
+       
+       public Attribute getAttribute(String name) {
+               return attributes.get(name);
+       }
+
+       private Resource data;
+       
+       public void setData(Resource data) {
+               this.data = data;
+       }
+       
+       public Resource getData() {
+               return data;
+       }
+       
+       public void setElementParser(XMLElementParser parser) {
+               this.elementParser = parser;
+       }
+       
+       public XMLElementParser getElementParser() {
+               return elementParser;
+       }
+       
+       public void setXMLParser(XMLParser parser) {
+               this.xmlParser = parser;
+       }
+       
+       public XMLParser getXMLParser() {
+               return xmlParser;
+       }
+
+       public void registerListChild(Resource predicate, ParserElement child) {
+               if (lists == null)
+                       lists = new MapList<>();
+               lists.add(predicate, child);
+       }
+
+       public void createLists(WriteGraph graph) throws DatabaseException {
+               if (lists == null)
+                       return;
+               Layer0 L0 = Layer0.getInstance(graph);
+               for (Resource predicate : lists.getKeys()) {
+                       List<Resource> children = new ArrayList<>();
+                       for (ParserElement child : lists.getValues(predicate))
+                               children.add(child.getData());
+                       Resource list = ListUtils.create(graph, L0.List, L0.List_Element, null, children);
+                       graph.claim(getData(), predicate, list);
+               }
+       }
+
 }
\ No newline at end of file