KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > netbeans > nbbuild > XMLUtil


1 /*
2  * The contents of this file are subject to the terms of the Common Development
3  * and Distribution License (the License). You may not use this file except in
4  * compliance with the License.
5  *
6  * You can obtain a copy of the License at http://www.netbeans.org/cddl.html
7  * or http://www.netbeans.org/cddl.txt.
8  *
9  * When distributing Covered Code, include this CDDL Header Notice in each file
10  * and include the License file at http://www.netbeans.org/cddl.txt.
11  * If applicable, add the following below the CDDL Header, with the fields
12  * enclosed by brackets [] replaced by your own identifying information:
13  * "Portions Copyrighted [year] [name of copyright owner]"
14  *
15  * The Original Software is NetBeans. The Initial Developer of the Original
16  * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
17  * Microsystems, Inc. All Rights Reserved.
18  */

19
20 package org.netbeans.nbbuild;
21
22 import java.io.IOException JavaDoc;
23 import java.io.OutputStream JavaDoc;
24 import java.io.StringReader JavaDoc;
25 import java.util.ArrayList JavaDoc;
26 import java.util.List JavaDoc;
27 import javax.xml.parsers.DocumentBuilder JavaDoc;
28 import javax.xml.parsers.DocumentBuilderFactory JavaDoc;
29 import javax.xml.parsers.ParserConfigurationException JavaDoc;
30 import javax.xml.transform.OutputKeys JavaDoc;
31 import javax.xml.transform.Result JavaDoc;
32 import javax.xml.transform.Source JavaDoc;
33 import javax.xml.transform.Transformer JavaDoc;
34 import javax.xml.transform.TransformerFactory JavaDoc;
35 import javax.xml.transform.TransformerFactoryConfigurationError JavaDoc;
36 import javax.xml.transform.dom.DOMSource JavaDoc;
37 import javax.xml.transform.stream.StreamResult JavaDoc;
38 import javax.xml.transform.stream.StreamSource JavaDoc;
39 import org.w3c.dom.DOMException JavaDoc;
40 import org.w3c.dom.DOMImplementation JavaDoc;
41 import org.w3c.dom.Document JavaDoc;
42 import org.w3c.dom.DocumentType JavaDoc;
43 import org.w3c.dom.Element JavaDoc;
44 import org.w3c.dom.Node JavaDoc;
45 import org.w3c.dom.NodeList JavaDoc;
46 import org.w3c.dom.Text JavaDoc;
47 import org.xml.sax.EntityResolver JavaDoc;
48 import org.xml.sax.ErrorHandler JavaDoc;
49 import org.xml.sax.InputSource JavaDoc;
50 import org.xml.sax.SAXException JavaDoc;
51
52 /**
53  * Utility class collecting library methods related to XML processing.
54  * @author Petr Kuzel, Jesse Glick
55  */

56 final class XMLUtil extends Object JavaDoc {
57
58     @SuppressWarnings JavaDoc("unchecked")
59     private static final ThreadLocal JavaDoc<DocumentBuilder JavaDoc>[] builderTL = new ThreadLocal JavaDoc[4];
60     static {
61         for (int i = 0; i < 4; i++) {
62             builderTL[i] = new ThreadLocal JavaDoc<DocumentBuilder JavaDoc>();
63         }
64     }
65     public static Document JavaDoc parse (
66             InputSource JavaDoc input,
67             boolean validate,
68             boolean namespaceAware,
69             ErrorHandler JavaDoc errorHandler,
70             EntityResolver JavaDoc entityResolver
71         ) throws IOException JavaDoc, SAXException JavaDoc {
72         
73         int index = (validate ? 0 : 1) + (namespaceAware ? 0 : 2);
74         DocumentBuilder JavaDoc builder = builderTL[index].get();
75         if (builder == null) {
76             DocumentBuilderFactory JavaDoc factory = DocumentBuilderFactory.newInstance();
77             factory.setValidating(validate);
78             factory.setNamespaceAware(namespaceAware);
79
80             try {
81                 builder = factory.newDocumentBuilder();
82             } catch (ParserConfigurationException JavaDoc ex) {
83                 throw new SAXException JavaDoc(ex);
84             }
85             builderTL[index].set(builder);
86         }
87         
88         if (errorHandler != null) {
89             builder.setErrorHandler(errorHandler);
90         }
91         
92         if (entityResolver != null) {
93             builder.setEntityResolver(entityResolver);
94         }
95         
96         return builder.parse(input);
97     }
98     
99     public static Document JavaDoc createDocument(String JavaDoc rootQName) throws DOMException JavaDoc {
100         DocumentBuilderFactory JavaDoc factory = DocumentBuilderFactory.newInstance();
101         try {
102             return factory.newDocumentBuilder().getDOMImplementation().createDocument(null, rootQName, null);
103         } catch (ParserConfigurationException JavaDoc ex) {
104             throw (DOMException JavaDoc)new DOMException JavaDoc(DOMException.NOT_SUPPORTED_ERR, "Cannot create parser").initCause(ex); // NOI18N
105
}
106     }
107     
108     private static DOMImplementation JavaDoc getDOMImplementation() throws DOMException JavaDoc { //can be made public
109

110         DocumentBuilderFactory JavaDoc factory = DocumentBuilderFactory.newInstance();
111     
112         try {
113             return factory.newDocumentBuilder().getDOMImplementation();
114         } catch (ParserConfigurationException JavaDoc ex) {
115             throw (DOMException JavaDoc)new DOMException JavaDoc(DOMException.NOT_SUPPORTED_ERR, "Cannot create parser").initCause(ex); // NOI18N
116
}
117     }
118
119     // Cf. org.openide.xml.XMLUtil.
120
private static final String JavaDoc IDENTITY_XSLT_WITH_INDENT =
121             "<xsl:stylesheet version='1.0' " + // NOI18N
122
"xmlns:xsl='http://www.w3.org/1999/XSL/Transform' " + // NOI18N
123
"xmlns:xalan='http://xml.apache.org/xslt' " + // NOI18N
124
"exclude-result-prefixes='xalan'>" + // NOI18N
125
"<xsl:output method='xml' indent='yes' xalan:indent-amount='4'/>" + // NOI18N
126
"<xsl:template match='@*|node()'>" + // NOI18N
127
"<xsl:copy>" + // NOI18N
128
"<xsl:apply-templates select='@*|node()'/>" + // NOI18N
129
"</xsl:copy>" + // NOI18N
130
"</xsl:template>" + // NOI18N
131
"</xsl:stylesheet>"; // NOI18N
132

133     public static void write(Document JavaDoc doc, OutputStream JavaDoc out) throws IOException JavaDoc {
134         // XXX note that this may fail to write out namespaces correctly if the document
135
// is created with namespaces and no explicit prefixes; however no code in
136
// this package is likely to be doing so
137
try {
138             Transformer JavaDoc t = TransformerFactory.newInstance().newTransformer(
139                     new StreamSource JavaDoc(new StringReader JavaDoc(IDENTITY_XSLT_WITH_INDENT)));
140             DocumentType JavaDoc dt = doc.getDoctype();
141             if (dt != null) {
142                 String JavaDoc pub = dt.getPublicId();
143                 if (pub != null) {
144                     t.setOutputProperty(OutputKeys.DOCTYPE_PUBLIC, pub);
145                 }
146                 t.setOutputProperty(OutputKeys.DOCTYPE_SYSTEM, dt.getSystemId());
147             }
148             t.setOutputProperty(OutputKeys.ENCODING, "UTF-8"); // NOI18N
149
Source JavaDoc source = new DOMSource JavaDoc(doc);
150             Result JavaDoc result = new StreamResult JavaDoc(out);
151             t.transform(source, result);
152         } catch (Exception JavaDoc e) {
153             throw (IOException JavaDoc)new IOException JavaDoc(e.toString()).initCause(e);
154         } catch (TransformerFactoryConfigurationError JavaDoc e) {
155             throw (IOException JavaDoc)new IOException JavaDoc(e.toString()).initCause(e);
156         }
157     }
158
159     public static void write(Element JavaDoc el, OutputStream JavaDoc out) throws IOException JavaDoc {
160         try {
161             Transformer JavaDoc t = TransformerFactory.newInstance().newTransformer(
162                     new StreamSource JavaDoc(new StringReader JavaDoc(IDENTITY_XSLT_WITH_INDENT)));
163             t.setOutputProperty(OutputKeys.ENCODING, "UTF-8"); // NOI18N
164
t.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes");
165             Source JavaDoc source = new DOMSource JavaDoc(el);
166             Result JavaDoc result = new StreamResult JavaDoc(out);
167             t.transform(source, result);
168         } catch (Exception JavaDoc e) {
169             throw (IOException JavaDoc) new IOException JavaDoc(e.toString()).initCause(e);
170         } catch (TransformerFactoryConfigurationError JavaDoc e) {
171             throw (IOException JavaDoc) new IOException JavaDoc(e.toString()).initCause(e);
172         }
173     }
174
175     /**
176      * Search for an XML element in the direct children of a parent.
177      * DOM provides a similar method but it does a recursive search
178      * which we do not want. It also gives a node list and we want
179      * only one result.
180      * @param parent a parent element
181      * @param name the intended local name
182      * @param namespace the intended namespace (or null)
183      * @return the one child element with that name, or null if none or more than one
184      */

185     public static Element JavaDoc findElement(Element JavaDoc parent, String JavaDoc name, String JavaDoc namespace) {
186         Element JavaDoc result = null;
187         NodeList JavaDoc l = parent.getChildNodes();
188         for (int i = 0; i < l.getLength(); i++) {
189             if (l.item(i).getNodeType() == Node.ELEMENT_NODE) {
190                 Element JavaDoc el = (Element JavaDoc)l.item(i);
191                 if ((namespace == null && name.equals(el.getTagName())) ||
192                     (namespace != null && name.equals(el.getLocalName()) &&
193                                           namespace.equals(el.getNamespaceURI()))) {
194                     if (result == null) {
195                         result = el;
196                     } else {
197                         return null;
198                     }
199                 }
200             }
201         }
202         return result;
203     }
204     
205     /**
206      * Extract nested text from an element.
207      * Currently does not handle coalescing text nodes, CDATA sections, etc.
208      * @param parent a parent element
209      * @return the nested text, or null if none was found
210      */

211     static String JavaDoc findText(Element JavaDoc parent) {
212         NodeList JavaDoc l = parent.getChildNodes();
213         for (int i = 0; i < l.getLength(); i++) {
214             if (l.item(i).getNodeType() == Node.TEXT_NODE) {
215                 Text JavaDoc text = (Text JavaDoc)l.item(i);
216                 return text.getNodeValue();
217             }
218         }
219         return null;
220     }
221     
222     /**
223      * Find all direct child elements of an element.
224      * More useful than {@link Element#getElementsByTagNameNS} because it does
225      * not recurse into recursive child elements.
226      * Children which are all-whitespace text nodes or comments are ignored; others cause
227      * an exception to be thrown.
228      * @param parent a parent element in a DOM tree
229      * @return a list of direct child elements (may be empty)
230      * @throws IllegalArgumentException if there are non-element children besides whitespace
231      */

232     static List JavaDoc<Element JavaDoc> findSubElements(Element JavaDoc parent) throws IllegalArgumentException JavaDoc {
233         NodeList JavaDoc l = parent.getChildNodes();
234         List JavaDoc<Element JavaDoc> elements = new ArrayList JavaDoc<Element JavaDoc>(l.getLength());
235         for (int i = 0; i < l.getLength(); i++) {
236             Node JavaDoc n = l.item(i);
237             if (n.getNodeType() == Node.ELEMENT_NODE) {
238                 elements.add((Element JavaDoc)n);
239             } else if (n.getNodeType() == Node.TEXT_NODE) {
240                 String JavaDoc text = ((Text JavaDoc)n).getNodeValue();
241                 if (text.trim().length() > 0) {
242                     throw new IllegalArgumentException JavaDoc("non-ws text encountered in " + parent + ": " + text); // NOI18N
243
}
244             } else if (n.getNodeType() == Node.COMMENT_NODE) {
245                 // OK, ignore
246
} else {
247                 throw new IllegalArgumentException JavaDoc("unexpected non-element child of " + parent + ": " + n); // NOI18N
248
}
249         }
250         return elements;
251     }
252     
253 }
254
Popular Tags