]> gerrit.simantics Code Review - simantics/interop.git/blob - 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
1 package org.simantics.xml.sax.base;
2
3 import java.io.Serializable;
4 import java.util.ArrayList;
5 import java.util.Collection;
6 import java.util.HashMap;
7 import java.util.List;
8 import java.util.Map;
9
10 import org.simantics.db.Resource;
11 import org.simantics.db.WriteGraph;
12 import org.simantics.db.common.utils.ListUtils;
13 import org.simantics.db.exception.DatabaseException;
14 import org.simantics.layer0.Layer0;
15 import org.simantics.utils.datastructures.MapList;
16 import org.xml.sax.Attributes;
17
18 public class ParserElement implements Serializable {
19         private static final long serialVersionUID = -5207502156942818875L;
20         private String uri;
21         private String localName;
22         private String qName;
23         Map<String, Attribute> attributes;
24         MapList<Resource, ParserElement> lists;
25
26         XMLElementParser elementParser;
27         XMLParser xmlParser;
28
29         Map<String,String> nsMap;
30         
31         private ParserElement parent;
32         
33         public ParserElement(String uri, String localName, String qName, Attributes attributes) {
34                 this.uri = uri;
35                 this.localName = localName;
36                 this.qName = qName;
37                 int attrCount = attributes.getLength();
38                 this.attributes = new HashMap<>(attrCount);
39                 for (int i = 0; i < attrCount; i++) {
40                         this.attributes.put(attributes.getLocalName(i),new Attribute(attributes.getLocalName(i),attributes.getQName(i),attributes.getURI(i),attributes.getValue(i)));
41                 }
42                 processNS();
43         }
44         
45         public ParserElement(String uri, String localName, String qName, Collection<Attribute> attributes) {
46                 this.uri = uri;
47                 this.localName = localName;
48                 this.qName = qName;
49                 this.attributes = new HashMap<>(attributes.size());
50                 for (Attribute a : attributes) {
51                         this.attributes.put(a.localName,new Attribute(a.localName,a.qName,a.uri,a.value));
52                 }
53                 processNS();
54         }
55         
56         public ParserElement(ParserElement parent, String uri, String localName, String qName, Attributes attributes) {
57                 this.parent = parent;
58                 this.uri = uri;
59                 this.localName = localName;
60                 this.qName = qName;
61                 int attrCount = attributes.getLength();
62                 this.attributes = new HashMap<>(attrCount);
63                 for (int i = 0; i < attrCount; i++) {
64                         this.attributes.put(attributes.getLocalName(i),new Attribute(attributes.getLocalName(i),attributes.getQName(i),attributes.getURI(i),attributes.getValue(i)));
65                 }
66                 processNS();
67         }
68         
69         public ParserElement(ParserElement parent, String uri, String localName, String qName, Collection<Attribute> attributes) {
70                 this.parent = parent;
71                 this.uri = uri;
72                 this.localName = localName;
73                 this.qName = qName;
74                 this.attributes = new HashMap<>(attributes.size());
75                 for (Attribute a : attributes) {
76                         this.attributes.put(a.localName,new Attribute(a.localName,a.qName,a.uri,a.value));
77                 }
78                 processNS();
79         }
80         
81         private void processNS() {
82                 
83                 nsMap = new HashMap<>();
84                 for (Attribute a : attributes.values()) {
85                         if (a.localName.startsWith("xmlns")) {
86                                 String ns[] = a.localName.split(":");
87                                 if (ns.length == 2) {
88                                         nsMap.put(ns[1], a.value);
89                                 }
90                         }
91                 }
92                 Map<String, Attribute> newAttrs = new HashMap<>();
93                 for (Attribute a : attributes.values()) {
94                         String ns[] = a.localName.split(":");
95                         if (ns.length == 2) {
96                                 if ("xmlns".equals(ns[0]))
97                                         continue;
98                                 String namespace = getNS(ns[0]);
99                                 if (namespace != null) {
100                                         if (newAttrs.put(ns[1], new Attribute(ns[1], a.qName, namespace, a.value)) != null)
101                                                 throw new RuntimeException("XML parser internal error, overlapping attribute names " + ns[1]);
102                                 } else {
103                                         throw new RuntimeException("XML parser error, namespace " + ns[0] + " for attribute " + a.localName + " not defined.");
104                                 }
105                         } else {
106                                 newAttrs.put(a.localName, a);
107                         }
108                 }
109                 attributes = newAttrs;
110                 
111                 String nameNs[] = qName.split(":");
112                 if (nameNs.length == 2) {
113                         localName = nameNs[1];
114                         if (uri.length() == 0)
115                                 uri = getNS(nameNs[0]) + "/"+localName;
116                 } else if (localName.length() == 0) {
117                         localName = qName;
118                 }
119         }
120         
121         public String getNS(String key) {
122                 String ns = nsMap.get(key);
123                 if (ns == null && parent != null)
124                         ns = parent.getNS(key);
125                 return ns;
126         }
127
128         public String getUri() {
129                 return uri;
130         }
131
132         public String getLocalName() {
133                 return localName;
134         }
135
136         public String getQName() {
137                 return qName;
138         }
139
140         public Collection<Attribute> getAttributes() {
141                 return attributes.values();
142         }
143         
144         public Attribute getAttribute(String name) {
145                 return attributes.get(name);
146         }
147
148         private Resource data;
149         
150         public void setData(Resource data) {
151                 this.data = data;
152         }
153         
154         public Resource getData() {
155                 return data;
156         }
157         
158         public void setElementParser(XMLElementParser parser) {
159                 this.elementParser = parser;
160         }
161         
162         public XMLElementParser getElementParser() {
163                 return elementParser;
164         }
165         
166         public void setXMLParser(XMLParser parser) {
167                 this.xmlParser = parser;
168         }
169         
170         public XMLParser getXMLParser() {
171                 return xmlParser;
172         }
173
174         public void registerListChild(Resource predicate, ParserElement child) {
175                 if (lists == null)
176                         lists = new MapList<>();
177                 lists.add(predicate, child);
178         }
179
180         public void createLists(WriteGraph graph) throws DatabaseException {
181                 if (lists == null)
182                         return;
183                 Layer0 L0 = Layer0.getInstance(graph);
184                 for (Resource predicate : lists.getKeys()) {
185                         List<Resource> children = new ArrayList<>();
186                         for (ParserElement child : lists.getValues(predicate))
187                                 children.add(child.getData());
188                         Resource list = ListUtils.create(graph, L0.List, L0.List_Element, null, children);
189                         graph.claim(getData(), predicate, list);
190                 }
191         }
192
193 }