KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > cocoon > forms > util > DomHelper


1 /*
2  * Copyright 1999-2005 The Apache Software Foundation.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */

16 package org.apache.cocoon.forms.util;
17
18 import java.io.IOException JavaDoc;
19 import java.util.ArrayList JavaDoc;
20 import java.util.HashMap JavaDoc;
21 import java.util.LinkedList JavaDoc;
22 import java.util.List JavaDoc;
23 import java.util.ListIterator JavaDoc;
24 import java.util.Map JavaDoc;
25
26 import org.apache.avalon.framework.service.ServiceException;
27 import org.apache.avalon.framework.service.ServiceManager;
28 import org.apache.cocoon.util.location.Location;
29 import org.apache.cocoon.util.location.LocationAttributes;
30 import org.apache.cocoon.xml.SaxBuffer;
31 import org.apache.cocoon.xml.dom.DOMBuilder;
32 import org.apache.cocoon.xml.dom.DOMStreamer;
33 import org.apache.commons.lang.BooleanUtils;
34 import org.apache.excalibur.xml.sax.SAXParser;
35 import org.apache.excalibur.xml.sax.XMLizable;
36 import org.w3c.dom.Attr JavaDoc;
37 import org.w3c.dom.CDATASection JavaDoc;
38 import org.w3c.dom.Document JavaDoc;
39 import org.w3c.dom.Element JavaDoc;
40 import org.w3c.dom.NamedNodeMap JavaDoc;
41 import org.w3c.dom.Node JavaDoc;
42 import org.w3c.dom.NodeList JavaDoc;
43 import org.w3c.dom.Text JavaDoc;
44 import org.xml.sax.ContentHandler JavaDoc;
45 import org.xml.sax.InputSource JavaDoc;
46 import org.xml.sax.SAXException JavaDoc;
47 import org.xml.sax.SAXNotSupportedException JavaDoc;
48
49 /**
50  * Helper class to create and retrieve information from DOM-trees. It provides
51  * some functionality comparable to what's found in Avalon's Configuration
52  * objects. These lasts one could however not be used by Cocoon Forms because they
53  * don't provide an accurate model of an XML file (no mixed content,
54  * no namespaced attributes, no namespace declarations, ...).
55  *
56  * <p>This class depends specifically on the Xerces DOM implementation to be
57  * able to provide information about the location of elements in their source
58  * XML file. See the {@link #getLocation(Element)} method.
59  *
60  * @version $Id: DomHelper.java 328353 2005-10-25 12:59:42Z sylvain $
61  */

62 public class DomHelper {
63
64     public static final String JavaDoc XMLNS_URI = "http://www.w3.org/2000/xmlns/";
65
66     public static Location getLocationObject(Element JavaDoc element) {
67         return LocationAttributes.getLocation(element);
68     }
69
70     /**
71      * Retrieves the location of an element node in the source file from which
72      * the Document was created. This will only work for Document's created
73      * with the method {@link #parse(InputSource)} of this class.
74      */

75     public static String JavaDoc getLocation(Element JavaDoc element) {
76         return LocationAttributes.getLocationString(element);
77     }
78     
79     public static String JavaDoc getSystemIdLocation(Element JavaDoc element) {
80         return LocationAttributes.getURI(element);
81     }
82     
83     public static int getLineLocation(Element JavaDoc element) {
84         return LocationAttributes.getLine(element);
85     }
86
87     public static int getColumnLocation(Element JavaDoc element) {
88         return LocationAttributes.getColumn(element);
89     }
90
91     /**
92      * Returns all Element children of an Element that belong to the given
93      * namespace.
94      */

95     public static Element JavaDoc[] getChildElements(Element JavaDoc element, String JavaDoc namespace) {
96         ArrayList JavaDoc elements = new ArrayList JavaDoc();
97         NodeList JavaDoc nodeList = element.getChildNodes();
98         for (int i = 0; i < nodeList.getLength(); i++) {
99             Node JavaDoc node = nodeList.item(i);
100             if (node instanceof Element JavaDoc
101                     && namespace.equals(node.getNamespaceURI()))
102                 elements.add(node);
103         }
104         return (Element JavaDoc[])elements.toArray(new Element JavaDoc[elements.size()]);
105     }
106
107     /**
108      * Returns all Element children of an Element that belong to the given
109      * namespace and have the given local name.
110      */

111     public static Element JavaDoc[] getChildElements(Element JavaDoc element,
112             String JavaDoc namespace, String JavaDoc localName) {
113         ArrayList JavaDoc elements = new ArrayList JavaDoc();
114         NodeList JavaDoc nodeList = element.getChildNodes();
115         for (int i = 0; i < nodeList.getLength(); i++) {
116             Node JavaDoc node = nodeList.item(i);
117             if (node instanceof Element JavaDoc
118                     && namespace.equals(node.getNamespaceURI())
119                     && localName.equals(node.getLocalName())) {
120                 elements.add(node);
121             }
122         }
123         return (Element JavaDoc[])elements.toArray(new Element JavaDoc[elements.size()]);
124     }
125
126     /**
127      * Returns the first child element with the given namespace and localName,
128      * or null if there is no such element.
129      */

130     public static Element JavaDoc getChildElement(Element JavaDoc element, String JavaDoc namespace,
131             String JavaDoc localName) {
132         Element JavaDoc node = null;
133         try {
134             node = getChildElement(element, namespace, localName, false);
135         } catch (Exception JavaDoc e) {
136             node = null;
137         }
138         return node;
139     }
140
141     /**
142      * Returns the first child element with the given namespace and localName,
143      * or null if there is no such element and required flag is unset or
144      * throws an Exception if the "required" flag is set.
145      */

146     public static Element JavaDoc getChildElement(Element JavaDoc element, String JavaDoc namespace,
147             String JavaDoc localName, boolean required) throws Exception JavaDoc {
148         NodeList JavaDoc nodeList = element.getChildNodes();
149         for (int i = 0; i < nodeList.getLength(); i++) {
150             Node JavaDoc node = nodeList.item(i);
151             if (node instanceof Element JavaDoc
152                     && namespace.equals(node.getNamespaceURI())
153                     && localName.equals(node.getLocalName())) {
154                 return (Element JavaDoc)node;
155             }
156         }
157         if (required) {
158             throw new Exception JavaDoc("Missing element \"" + localName +
159                     "\" as child of element \"" + element.getTagName() +
160                     "\" at " + DomHelper.getLocation(element));
161         } else {
162             return null;
163         }
164     }
165
166     /**
167      * Returns the value of an element's attribute, but throws an exception
168      * if the element has no such attribute.
169      */

170     public static String JavaDoc getAttribute(Element JavaDoc element, String JavaDoc attributeName)
171             throws Exception JavaDoc {
172         String JavaDoc attrValue = element.getAttribute(attributeName);
173         if (attrValue.equals("")) {
174             throw new Exception JavaDoc("Missing attribute \"" + attributeName +
175                     "\" on element \"" + element.getTagName() +
176                     "\" at " + getLocation(element));
177         }
178         return attrValue;
179     }
180
181     /**
182      * Returns the value of an element's attribute, or a default value if the
183      * element has no such attribute.
184      */

185     public static String JavaDoc getAttribute(Element JavaDoc element, String JavaDoc attributeName,
186             String JavaDoc defaultValue) {
187         String JavaDoc attrValue = element.getAttribute(attributeName);
188         if (attrValue.equals("")) {
189             return defaultValue;
190         }
191         return attrValue;
192     }
193
194     public static int getAttributeAsInteger(Element JavaDoc element,
195             String JavaDoc attributeName) throws Exception JavaDoc {
196         String JavaDoc attrValue = getAttribute(element, attributeName);
197         try {
198             return Integer.parseInt(attrValue);
199         } catch (NumberFormatException JavaDoc e) {
200             throw new Exception JavaDoc("Cannot parse the value \"" + attrValue +
201                     "\" as an integer in the attribute \"" + attributeName +
202                     "\" on the element \"" + element.getTagName() +
203                     "\" at " + getLocation(element));
204         }
205     }
206
207     public static int getAttributeAsInteger(Element JavaDoc element,
208             String JavaDoc attributeName, int defaultValue) throws Exception JavaDoc {
209         String JavaDoc attrValue = element.getAttribute(attributeName);
210         if (attrValue.equals("")) {
211             return defaultValue;
212         } else {
213             try {
214                 return Integer.parseInt(attrValue);
215             } catch (NumberFormatException JavaDoc e) {
216                 throw new Exception JavaDoc("Cannot parse the value \"" + attrValue +
217                         "\" as an integer in the attribute \"" +
218                         attributeName + "\" on the element \"" +
219                         element.getTagName() + "\" at " +
220                         getLocation(element));
221             }
222         }
223     }
224
225     public static boolean getAttributeAsBoolean(Element JavaDoc element,
226                 String JavaDoc attributeName, boolean defaultValue) {
227         String JavaDoc attrValue = element.getAttribute(attributeName);
228         Boolean JavaDoc result;
229         try {
230             result = BooleanUtils.toBooleanObject(attrValue, "true", "false", null);
231         } catch (IllegalArgumentException JavaDoc iae) {
232             result = null;
233         }
234         if (result != null) {
235             return result.booleanValue();
236         }
237         try {
238             result = BooleanUtils.toBooleanObject(attrValue, "yes", "no", null);
239         } catch (IllegalArgumentException JavaDoc iae) {
240             result = null;
241         }
242         if (result != null) {
243             return result.booleanValue();
244         }
245         return defaultValue;
246     }
247
248     public static String JavaDoc getElementText(Element JavaDoc element) {
249         StringBuffer JavaDoc value = new StringBuffer JavaDoc();
250         NodeList JavaDoc nodeList = element.getChildNodes();
251         for (int i = 0; i < nodeList.getLength(); i++) {
252             Node JavaDoc node = nodeList.item(i);
253             if (node instanceof Text JavaDoc || node instanceof CDATASection JavaDoc) {
254                 value.append(node.getNodeValue());
255             }
256         }
257         return value.toString();
258     }
259
260     /**
261      * Returns the content of the given Element as an object implementing the
262      * XMLizable interface. Practically speaking, the implementation uses the
263      * {@link SaxBuffer} class. The XMLizable object will be a standalone blurb
264      * of SAX events, not producing start/endDocument calls and containing all
265      * necessary namespace declarations.
266      */

267     public static XMLizable compileElementContent(Element JavaDoc element) {
268         // Remove location information
269
LocationAttributes.remove(element, true);
270
271         SaxBuffer saxBuffer = new SaxBuffer();
272         DOMStreamer domStreamer = new DOMStreamer();
273         domStreamer.setContentHandler(saxBuffer);
274
275         NodeList JavaDoc childNodes = element.getChildNodes();
276         for (int i = 0; i < childNodes.getLength(); i++) {
277             try {
278                 domStreamer.stream(childNodes.item(i));
279             } catch (SAXException JavaDoc e) {
280                 // It's unlikely that an exception will occur here,
281
// so use a runtime exception
282
throw new RuntimeException JavaDoc(
283                         "Error in DomHelper.compileElementContent: " +
284                         e.toString());
285             }
286         }
287         return saxBuffer;
288     }
289
290     /**
291      * Creates a W3C Document that remembers the location of each element in
292      * the source file. The location of element nodes can then be retrieved
293      * using the {@link #getLocation(Element)} method.
294      *
295      * @param inputSource the inputSource to read the document from
296      * @param manager the service manager where to lookup the entity resolver
297      */

298     public static Document JavaDoc parse(InputSource JavaDoc inputSource, ServiceManager manager)
299             throws SAXException JavaDoc, SAXNotSupportedException JavaDoc, IOException JavaDoc, ServiceException {
300         
301         SAXParser parser = (SAXParser)manager.lookup(SAXParser.ROLE);
302         DOMBuilder builder = new DOMBuilder();
303         
304         // Enhance the sax stream with location information
305
ContentHandler JavaDoc locationHandler = new LocationAttributes.Pipe(builder);
306         
307         try {
308             parser.parse(inputSource, locationHandler);
309         } finally {
310             manager.release(parser);
311         }
312         
313         return builder.getDocument();
314     }
315
316     public static Map JavaDoc getLocalNSDeclarations(Element JavaDoc elm)
317     {
318         return addLocalNSDeclarations(elm, null);
319     }
320     
321     private static Map JavaDoc addLocalNSDeclarations(Element JavaDoc elm, Map JavaDoc nsDeclarations)
322     {
323         NamedNodeMap JavaDoc atts = elm.getAttributes();
324         int attsSize = atts.getLength();
325
326         for (int i = 0; i < attsSize; i++)
327         {
328             Attr JavaDoc attr = (Attr JavaDoc)atts.item(i);
329             if (XMLNS_URI.equals(attr.getNamespaceURI()))
330             {
331                 String JavaDoc nsUri = attr.getValue();
332                 String JavaDoc pfx = attr.getLocalName();
333                 if (nsDeclarations == null)
334                     nsDeclarations = new HashMap JavaDoc();
335                 nsDeclarations.put(nsUri, pfx);
336             }
337         }
338         return nsDeclarations; }
339     
340     public static Map JavaDoc getInheritedNSDeclarations(Element JavaDoc elm)
341     {
342         List JavaDoc ancestorsAndSelf = new LinkedList JavaDoc();
343         Element JavaDoc current = elm;
344         while (current != null)
345         {
346             ancestorsAndSelf.add(current);
347             Node JavaDoc parent = current.getParentNode();
348             if (parent.getNodeType() == Node.ELEMENT_NODE)
349                 current = (Element JavaDoc)parent;
350             else
351                 current = null;
352         }
353         
354         Map JavaDoc nsDeclarations = null;
355         ListIterator JavaDoc iter = ancestorsAndSelf.listIterator(ancestorsAndSelf.size());
356         while (iter.hasPrevious())
357         {
358             Element JavaDoc element = (Element JavaDoc) iter.previous();
359             nsDeclarations = addLocalNSDeclarations(element, nsDeclarations);
360         }
361         
362         return nsDeclarations;
363     }
364 }
365
Popular Tags