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.security.AccessController;
53 import java.security.PrivilegedActionException;
54 import java.security.PrivilegedExceptionAction;
55 import java.util.Iterator;
56 import java.util.Map;
57
58 import javax.xml.parsers.DocumentBuilder;
59 import javax.xml.parsers.DocumentBuilderFactory;
60 import javax.xml.parsers.FactoryConfigurationError;
61 import javax.xml.parsers.ParserConfigurationException;
62
63 import org.w3c.dom.Document;
64 import org.w3c.dom.Element;
65 import org.w3c.dom.Node;
66 import org.xml.sax.InputSource;
67 import org.xml.sax.SAXException;
68
69 /***
70 * A helper class for creating a W3C DOM tree
71 *
72 * @author <a href="mailto:james@coredevelopers.net">James Strachan</a>
73 * @version $Revision: 1.6 $
74 */
75 public class DOMBuilder extends BuilderSupport {
76
77 Document document;
78 DocumentBuilder documentBuilder;
79
80 public static DOMBuilder newInstance() throws ParserConfigurationException, FactoryConfigurationError {
81 DocumentBuilder documentBuilder = null;
82 try {
83 documentBuilder = (DocumentBuilder) AccessController.doPrivileged(new PrivilegedExceptionAction() {
84 public Object run() throws ParserConfigurationException {
85 return DocumentBuilderFactory.newInstance().newDocumentBuilder();
86 }
87 });
88 } catch (PrivilegedActionException pae) {
89 Exception e = pae.getException();
90 if (e instanceof ParserConfigurationException) {
91 throw (ParserConfigurationException) e;
92 } else {
93 throw new RuntimeException(e);
94 }
95 }
96 return new DOMBuilder(documentBuilder);
97 }
98
99 public static Document parse(Reader reader) throws SAXException, IOException, ParserConfigurationException {
100 DocumentBuilder documentBuilder = null;
101 try {
102 documentBuilder = (DocumentBuilder) AccessController.doPrivileged(new PrivilegedExceptionAction() {
103 public Object run() throws ParserConfigurationException {
104 return DocumentBuilderFactory.newInstance().newDocumentBuilder();
105 }
106 });
107 } catch (PrivilegedActionException pae) {
108 Exception e = pae.getException();
109 if (e instanceof ParserConfigurationException) {
110 throw (ParserConfigurationException) e;
111 } else {
112 throw new RuntimeException(e);
113 }
114 }
115 return documentBuilder.parse(new InputSource(reader));
116 }
117
118 public DOMBuilder(Document document) {
119 this.document = document;
120 }
121
122 public DOMBuilder(DocumentBuilder documentBuilder) {
123 this.documentBuilder = documentBuilder;
124 }
125
126 protected void setParent(Object parent, Object child) {
127 Node current = (Node) parent;
128 Node node = (Node) child;
129
130 current.appendChild(node);
131 }
132
133 protected Object createNode(Object name) {
134 if (document == null) {
135 document = createDocument();
136 }
137 if (name instanceof QName) {
138 QName qname = (QName) name;
139 return document.createElementNS(qname.getNamespaceURI(), qname.getQualifiedName());
140 }
141 else {
142 return document.createElement(name.toString());
143 }
144 }
145
146 protected Document createDocument() {
147 if (documentBuilder == null) {
148 throw new IllegalArgumentException("No Document or DOMImplementation available so cannot create Document");
149 }
150 else {
151 return documentBuilder.newDocument();
152 }
153 }
154
155 protected Object createNode(Object name, Object value) {
156 Element element = (Element) createNode(name);
157 element.appendChild(document.createTextNode(value.toString()));
158 return element;
159 }
160
161 protected Object createNode(Object name, Map attributes, Object value) {
162 Element element = (Element) createNode(name, attributes);
163 element.appendChild(document.createTextNode(value.toString()));
164 return element;
165 }
166
167 protected Object createNode(Object name, Map attributes) {
168 Element element = (Element) createNode(name);
169 for (Iterator iter = attributes.entrySet().iterator(); iter.hasNext();) {
170 Map.Entry entry = (Map.Entry) iter.next();
171 String attrName = entry.getKey().toString();
172 Object value = entry.getValue();
173 if ("xmlns".equals(attrName)) {
174 if (value instanceof Map) {
175 appendNamespaceAttributes(element, (Map) value);
176 }
177 else {
178 throw new IllegalArgumentException("The value of the xmlns attribute must be a Map of QNames to String URIs");
179 }
180 }
181 else {
182 element.setAttribute(attrName, value.toString());
183 }
184 }
185 return element;
186 }
187
188 protected void appendNamespaceAttributes(Element element, Map attributes) {
189 for (Iterator iter = attributes.entrySet().iterator(); iter.hasNext();) {
190 Map.Entry entry = (Map.Entry) iter.next();
191 Object key = entry.getKey();
192 Object value = entry.getValue();
193 if (value == null) {
194 throw new IllegalArgumentException("The value of key: " + key + " cannot be null");
195 }
196 if (key instanceof String) {
197 String prefix = (String) key;
198
199
200
201
202 element.setAttributeNS("", prefix, value.toString());
203 }
204 else if (key instanceof QName) {
205 QName qname = (QName) key;
206 element.setAttributeNS(qname.getNamespaceURI(), qname.getQualifiedName(), value.toString());
207 }
208 else {
209 throw new IllegalArgumentException("The key: " + key + " should be an instanceof of " + QName.class);
210 }
211 }
212 }
213 }