1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.apache.commons.modeler.util;
17
18 import java.io.IOException;
19 import java.io.InputStream;
20 import java.io.OutputStream;
21 import java.io.StringReader;
22
23 import javax.xml.parsers.DocumentBuilder;
24 import javax.xml.parsers.DocumentBuilderFactory;
25 import javax.xml.parsers.ParserConfigurationException;
26 import javax.xml.transform.OutputKeys;
27 import javax.xml.transform.Transformer;
28 import javax.xml.transform.TransformerException;
29 import javax.xml.transform.TransformerFactory;
30 import javax.xml.transform.dom.DOMSource;
31 import javax.xml.transform.stream.StreamResult;
32
33 import org.w3c.dom.Document;
34 import org.w3c.dom.NamedNodeMap;
35 import org.w3c.dom.Node;
36 import org.xml.sax.EntityResolver;
37 import org.xml.sax.InputSource;
38 import org.xml.sax.SAXException;
39
40
41 /***
42 * Few simple utils to read DOM
43 *
44 * @author Costin Manolache
45 */
46 public class DomUtil {
47 private static org.apache.commons.logging.Log log=
48 org.apache.commons.logging.LogFactory.getLog( DomUtil.class );
49
50
51
52 /*** Get the trimed text content of a node or null if there is no text
53 */
54 public static String getContent(Node n ) {
55 if( n==null ) return null;
56 Node n1=DomUtil.getChild(n, Node.TEXT_NODE);
57
58 if( n1==null ) return null;
59
60 String s1=n1.getNodeValue();
61 return s1.trim();
62 }
63
64 /*** Get the first element child.
65 * @param parent lookup direct childs
66 * @param name name of the element. If null return the first element.
67 */
68 public static Node getChild( Node parent, String name ) {
69 if( parent==null ) return null;
70 Node first=parent.getFirstChild();
71 if( first==null ) return null;
72
73 for (Node node = first; node != null;
74 node = node.getNextSibling()) {
75
76 if( node.getNodeType()!=Node.ELEMENT_NODE)
77 continue;
78 if( name != null &&
79 name.equals( node.getNodeName() ) ) {
80 return node;
81 }
82 if( name == null ) {
83 return node;
84 }
85 }
86 return null;
87 }
88
89 public static String getAttribute(Node element, String attName ) {
90 NamedNodeMap attrs=element.getAttributes();
91 if( attrs==null ) return null;
92 Node attN=attrs.getNamedItem(attName);
93 if( attN==null ) return null;
94 return attN.getNodeValue();
95 }
96
97 public static void setAttribute(Node node, String attName, String val) {
98 NamedNodeMap attributes=node.getAttributes();
99 Node attNode=node.getOwnerDocument().createAttribute(attName);
100 attNode.setNodeValue( val );
101 attributes.setNamedItem(attNode);
102 }
103
104 public static void removeAttribute( Node node, String attName ) {
105 NamedNodeMap attributes=node.getAttributes();
106 attributes.removeNamedItem(attName);
107 }
108
109
110 /*** Set or replace the text value
111 */
112 public static void setText(Node node, String val) {
113 Node chld=DomUtil.getChild(node, Node.TEXT_NODE);
114 if( chld == null ) {
115 Node textN=node.getOwnerDocument().createTextNode(val);
116 node.appendChild(textN);
117 return;
118 }
119
120 chld.setNodeValue(val);
121 }
122
123 /*** Find the first direct child with a given attribute.
124 * @param parent
125 * @param elemName name of the element, or null for any
126 * @param attName attribute we're looking for
127 * @param attVal attribute value or null if we just want any
128 */
129 public static Node findChildWithAtt(Node parent, String elemName,
130 String attName, String attVal) {
131
132 Node child=DomUtil.getChild(parent, Node.ELEMENT_NODE);
133 if( attVal== null ) {
134 while( child!= null &&
135 ( elemName==null || elemName.equals( child.getNodeName())) &&
136 DomUtil.getAttribute(child, attName) != null ) {
137 child=getNext(child, elemName, Node.ELEMENT_NODE );
138 }
139 } else {
140 while( child!= null &&
141 ( elemName==null || elemName.equals( child.getNodeName())) &&
142 ! attVal.equals( DomUtil.getAttribute(child, attName)) ) {
143 child=getNext(child, elemName, Node.ELEMENT_NODE );
144 }
145 }
146 return child;
147 }
148
149
150 /*** Get the first child's content ( ie it's included TEXT node ).
151 */
152 public static String getChildContent( Node parent, String name ) {
153 Node first=parent.getFirstChild();
154 if( first==null ) return null;
155 for (Node node = first; node != null;
156 node = node.getNextSibling()) {
157
158 if( name.equals( node.getNodeName() ) ) {
159 return getContent( node );
160 }
161 }
162 return null;
163 }
164
165 /*** Get the first direct child with a given type
166 */
167 public static Node getChild( Node parent, int type ) {
168 Node n=parent.getFirstChild();
169 while( n!=null && type != n.getNodeType() ) {
170 n=n.getNextSibling();
171 }
172 if( n==null ) return null;
173 return n;
174 }
175
176 /*** Get the next sibling with the same name and type
177 */
178 public static Node getNext( Node current ) {
179 String name=current.getNodeName();
180 int type=current.getNodeType();
181 return getNext( current, name, type);
182 }
183
184 /*** Return the next sibling with a given name and type
185 */
186 public static Node getNext( Node current, String name, int type) {
187 Node first=current.getNextSibling();
188 if( first==null ) return null;
189
190 for (Node node = first; node != null;
191 node = node.getNextSibling()) {
192
193 if( type >= 0 && node.getNodeType() != type ) continue;
194
195 if( name==null )
196 return node;
197 if( name.equals( node.getNodeName() ) ) {
198 return node;
199 }
200 }
201 return null;
202 }
203
204 public static class NullResolver implements EntityResolver {
205 public InputSource resolveEntity (String publicId,
206 String systemId)
207 throws SAXException, IOException
208 {
209 if( log.isTraceEnabled())
210 log.trace("ResolveEntity: " + publicId + " " + systemId);
211 return new InputSource(new StringReader(""));
212 }
213 }
214
215 public static void setAttributes( Object o, Node parent)
216 {
217 NamedNodeMap attrs=parent.getAttributes();
218 if( attrs==null ) return;
219
220 for (int i=0; i<attrs.getLength(); i++ ) {
221 Node n=attrs.item(i);
222 String name=n.getNodeName();
223 String value=n.getNodeValue();
224
225 if( log.isTraceEnabled() )
226 log.trace("Attribute " + parent.getNodeName() + " " +
227 name + "=" + value);
228 try {
229 IntrospectionUtils.setProperty(o, name, value);
230 } catch( Exception ex ) {
231 ex.printStackTrace();
232 }
233 }
234 }
235
236 /*** Read XML as DOM.
237 */
238 public static Document readXml(InputStream is)
239 throws SAXException, IOException, ParserConfigurationException
240 {
241 DocumentBuilderFactory dbf =
242 DocumentBuilderFactory.newInstance();
243
244 dbf.setValidating(false);
245 dbf.setIgnoringComments(false);
246 dbf.setIgnoringElementContentWhitespace(true);
247
248
249
250 DocumentBuilder db = null;
251 db = dbf.newDocumentBuilder();
252 db.setEntityResolver( new NullResolver() );
253
254
255
256 Document doc = db.parse(is);
257 return doc;
258 }
259
260 public static void writeXml( Node n, OutputStream os )
261 throws TransformerException
262 {
263 TransformerFactory tf=TransformerFactory.newInstance();
264
265 Transformer t=tf.newTransformer();
266 t.setOutputProperty(OutputKeys.INDENT, "yes");
267 t.transform(new DOMSource( n ), new StreamResult( os ));
268 }
269 }