1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46 package groovy.xml;
47
48 import groovy.util.BuilderSupport;
49
50 import java.io.IOException;
51 import java.io.Reader;
52 import java.util.Iterator;
53 import java.util.Map;
54
55 import javax.xml.parsers.DocumentBuilder;
56 import javax.xml.parsers.DocumentBuilderFactory;
57 import javax.xml.parsers.ParserConfigurationException;
58
59 import org.w3c.dom.Document;
60 import org.w3c.dom.Element;
61 import org.w3c.dom.Node;
62 import org.xml.sax.InputSource;
63 import org.xml.sax.SAXException;
64
65 /***
66 * A helper class for creating a W3C DOM tree
67 *
68 * @author <a href="mailto:james@coredevelopers.net">James Strachan</a>
69 * @version $Revision: 4132 $
70 */
71 public class DOMBuilder extends BuilderSupport {
72
73 Document document;
74 DocumentBuilder documentBuilder;
75
76 public static DOMBuilder newInstance() throws ParserConfigurationException {
77 return newInstance(false, true);
78 }
79
80 public static DOMBuilder newInstance(boolean validating, boolean namespaceAware) throws ParserConfigurationException {
81 DocumentBuilderFactory factory = FactorySupport.createDocumentBuilderFactory();
82 factory.setNamespaceAware(namespaceAware);
83 factory.setValidating(validating);
84 return new DOMBuilder(factory.newDocumentBuilder());
85 }
86
87 public static Document parse(Reader reader) throws SAXException, IOException, ParserConfigurationException {
88 return parse(reader, false, true);
89 }
90
91 public static Document parse(Reader reader, boolean validating, boolean namespaceAware)
92 throws SAXException, IOException, ParserConfigurationException {
93 DocumentBuilderFactory factory = FactorySupport.createDocumentBuilderFactory();
94 factory.setNamespaceAware(namespaceAware);
95 factory.setValidating(validating);
96 DocumentBuilder documentBuilder = factory.newDocumentBuilder();
97 return documentBuilder.parse(new InputSource(reader));
98 }
99
100 public DOMBuilder(Document document) {
101 this.document = document;
102 }
103
104 public DOMBuilder(DocumentBuilder documentBuilder) {
105 this.documentBuilder = documentBuilder;
106 }
107
108 protected void setParent(Object parent, Object child) {
109 Node current = (Node) parent;
110 Node node = (Node) child;
111
112 current.appendChild(node);
113 }
114
115 protected Object createNode(Object name) {
116 if (document == null) {
117 document = createDocument();
118 }
119 if (name instanceof QName) {
120 QName qname = (QName) name;
121 return document.createElementNS(qname.getNamespaceURI(), qname.getQualifiedName());
122 } else {
123 return document.createElement(name.toString());
124 }
125 }
126
127 protected Document createDocument() {
128 if (documentBuilder == null) {
129 throw new IllegalArgumentException("No Document or DOMImplementation available so cannot create Document");
130 } else {
131 return documentBuilder.newDocument();
132 }
133 }
134
135 protected Object createNode(Object name, Object value) {
136 Element element = (Element) createNode(name);
137 element.appendChild(document.createTextNode(value.toString()));
138 return element;
139 }
140
141 protected Object createNode(Object name, Map attributes, Object value) {
142 Element element = (Element) createNode(name, attributes);
143 element.appendChild(document.createTextNode(value.toString()));
144 return element;
145 }
146
147 protected Object createNode(Object name, Map attributes) {
148 Element element = (Element) createNode(name);
149 for (Iterator iter = attributes.entrySet().iterator(); iter.hasNext();) {
150 Map.Entry entry = (Map.Entry) iter.next();
151 String attrName = entry.getKey().toString();
152 Object value = entry.getValue();
153 if ("xmlns".equals(attrName)) {
154 if (value instanceof Map) {
155 appendNamespaceAttributes(element, (Map) value);
156 } else {
157 throw new IllegalArgumentException("The value of the xmlns attribute must be a Map of QNames to String URIs");
158 }
159 } else {
160
161 element.setAttribute(attrName, value.toString());
162 }
163 }
164 return element;
165 }
166
167 protected void appendNamespaceAttributes(Element element, Map attributes) {
168 for (Iterator iter = attributes.entrySet().iterator(); iter.hasNext();) {
169 Map.Entry entry = (Map.Entry) iter.next();
170 Object key = entry.getKey();
171 Object value = entry.getValue();
172 if (value == null) {
173 throw new IllegalArgumentException("The value of key: " + key + " cannot be null");
174 }
175 if (key instanceof String) {
176 String prefix = (String) key;
177
178
179
180
181 element.setAttributeNS("", prefix, value.toString());
182 } else if (key instanceof QName) {
183 QName qname = (QName) key;
184 element.setAttributeNS(qname.getNamespaceURI(), qname.getQualifiedName(), value.toString());
185 } else {
186 throw new IllegalArgumentException("The key: " + key + " should be an instanceof of " + QName.class);
187 }
188 }
189 }
190 }