KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > enhydra > barracuda > core > util > dom > DOMUtil


1 /*
2  * Copyright (C) 2001 Christian Cryder [christianc@granitepeaks.com]
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Lesser General Public
6  * License as published by the Free Software Foundation; either
7  * version 2.1 of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12  * Lesser General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser General Public
15  * License along with this library; if not, write to the Free Software
16  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17  *
18  * $Id: DOMUtil.java,v 1.11 2004/01/29 18:02:35 christianc Exp $
19  */

20 package org.enhydra.barracuda.core.util.dom;
21
22 import java.io.*;
23 import java.util.*;
24 import org.w3c.dom.*;
25
26 import org.enhydra.barracuda.core.util.*;
27 import org.enhydra.barracuda.plankton.*;
28
29 /**
30  * DOM related utility functions.
31  */

32 public class DOMUtil {
33
34     private static byte[] sep = System.getProperty("line.separator").getBytes();
35
36     /**
37      * Find the first text descendent node of an element.
38      * This recursively looks more than one level to search
39      * for text in font nodes, etc.
40      *
41      * @param node The starting node for the search.
42      * @return The text node or null if not found.
43      */

44     public static Text findFirstText(Node node) {
45         if (node instanceof Text) return (Text) node;
46         for (Node child = node.getFirstChild(); child!=null; child = child.getNextSibling()) {
47             Text text = findFirstText(child);
48             if (text!=null) return text;
49         }
50         return null;
51     }
52
53     /**
54      * Gets the first text descendent node of an element.
55      * This recursively looks more than one level to search
56      * for text in font nodes, etc. Throws a DOMException
57      * if the Text object is not found.
58      *
59      * @param node The starting node for the search.
60      * @return The text node or null if not found.
61      * @throws DOMException if the Text object is not found
62      */

63     public static Text getFirstText(Node node) {
64         Text text = findFirstText(node);
65         if (text==null) {
66             String JavaDoc msg = "No child text mode found for element";
67             String JavaDoc id = getID(node);
68             throw new DOMException((short) -1, msg+(id!=null ? "; id=\""+id+"\"" : ""));
69         }
70         return text;
71     }
72
73     /**
74      * Automatically set text in a Node. Basically looks for
75      * the first child Text node; if it finds one, it sets the
76      * text, if not, it creates a new one with the appropriate
77      * text. Throws a DOMException if it's illegal to add a Text
78      * child to the particular node.
79      *
80      * @param node the starting node for the search.
81      * @param node the text to be added
82      * @return the updated node
83      * @throws DOMException if the Text object is not found
84      */

85 /*
86     public static Node setTextInNode(Node node, String text) {
87         Text textComp = DOMUtil.findFirstText((Element) node);
88         if (textComp==null) {
89             textComp = node.getOwnerDocument().createTextNode(text);
90             node.appendChild(textComp);
91         } else {
92             textComp.setData(""+text);
93         }
94         return node;
95     }
96 */

97
98
99     /**
100      * Automatically set text in a Node. Basically we find the first
101      * Text node beneath the current node and replace it with a
102      * CDATASection for the incoming text. All other Text nodes are
103      * removed. Throws a DOMException if it's illegal to add a Text
104      * child to the particular node.
105      *
106      * @param node the starting node for the search.
107      * @param text the text to be set
108      * @param allowMarkupInText whether to allow markup in text to pass through unparsed
109      * @return the updated node
110      * @throws DOMException if the Text object is not found
111      */

112     public static Node setTextInNode(Node node, String JavaDoc text, boolean allowMarkupInText) {
113         //start by setting the value in the first text node we find with a comment
114
Comment comment = node.getOwnerDocument().createComment("");
115         Node newNode = null;
116         
117         //csc_092701.1 - support both encoded/unencoded text
118
if (allowMarkupInText) newNode = node.getOwnerDocument().createCDATASection(text);
119         else newNode = node.getOwnerDocument().createTextNode(text);
120 //System.out.println ("newNode: "+newNode);
121

122         Text textComp = DOMUtil.findFirstText((Element) node);
123 //System.out.println ("textComp:"+textComp);
124
if (textComp==null) {
125             node.appendChild(comment);
126         } else {
127             Node parent = textComp.getParentNode();
128             parent.replaceChild(comment, textComp);
129         }
130         
131         //now remove all the rest of the text nodes
132
removeAllTextNodes(node);
133
134         //now replace the comment with the newNode
135
Node parent = comment.getParentNode();
136         parent.replaceChild(newNode, comment);
137 //System.out.println ("parent: "+parent);
138
//System.out.println ("result: "+DOMUtil.findFirstText((Element) parent));
139
//DOMUtil.printStackTrace(parent.getOwnerDocument().getDocumentElement());
140
return node;
141     }
142     
143     /**
144      * Remove all text nodes below this node
145      *
146      * @param node The starting node for the search.
147      */

148     public static void removeAllTextNodes(Node node) {
149         if (node==null) return;
150         if (!node.hasChildNodes()) return;
151         NodeList nl = node.getChildNodes();
152         for (int i=nl.getLength()-1; i>=0; i--) {
153             Node n = (Node) nl.item(i);
154             if (n instanceof Text) node.removeChild(n);
155             else removeAllTextNodes(n);
156         }
157     }
158     
159     /**
160      * Given a Node name, return the "id" attribute if it exists.
161      * If it does not exist, return null instead. This is basically
162      * just a convenience method to cast the node to element and
163      * return the id from that.
164      *
165      * @param node the node name in question
166      * @return the id value for the given node, if it exists. null if
167      * doesn't
168      */

169     public static String JavaDoc getID(Node node) {
170         return getID(node, null);
171     }
172
173     /**
174      * Given a Node, return the "id" attribute if it exists.
175      * If it does not exist, return nullResponse instead. This is basically
176      * just a convenience method to cast the node to element and
177      * return the id from that.
178      *
179      * @param node the node in question
180      * @param nullResponse the response to be returned if the id attribute
181      * does not exist
182      * @return the id value for the given node, if it exists. null if
183      * doesn't
184      */

185     public static String JavaDoc getID(Node node, String JavaDoc nullResponse) {
186         String JavaDoc nodeName = nullResponse;
187         if (node instanceof Element) {
188             nodeName = ((Element) node).getAttribute("id");
189         }
190         return nodeName;
191     }
192
193     /**
194      * <p>utility method to recursively print the stack trace for a DOM Node</p>
195      */

196     public static void printStackTrace(Node node) {
197         printStackTrace(node, System.out, 0);
198     }
199
200     /**
201      * <p>utility method to recursively print the stack trace for a DOM Node</p>
202      *
203      * <p>Bounds: <br>
204      * If depth < 0, the method returns immediately</p>
205      *
206      * @param node the node in question
207      * @param out OutputStream to print to
208      * @param depth inset depth at which to start printing
209      */

210     public static void printStackTrace(Node node, OutputStream out, int depth) {
211         if (depth<0) depth = 0;
212         if (depth>25) depth = 25;
213         String JavaDoc spaces = " ";
214         String JavaDoc inset = spaces.substring(0,depth*3);
215         print (out, inset+node.getClass().getName()+"@"+Integer.toHexString(node.hashCode()));
216         StringBuffer JavaDoc sb = new StringBuffer JavaDoc(200);
217         String JavaDoc sep = "";
218         Iterator it = Classes.getAllInterfaces(node).iterator();
219         while (it.hasNext()) {
220             sb.append(sep+Classes.getShortClassName((Class JavaDoc) it.next()));
221             sep = ", ";
222         }
223         print (out, inset+" implements: {"+sb.toString()+"}");
224         print (out, inset+" name:"+node.getNodeName());
225         print (out, inset+" attr:"+(node.hasAttributes() ? "" : " (n/a)"));
226         if (node.hasAttributes()) {
227             NamedNodeMap nnm = node.getAttributes();
228             for (int i=0,max=nnm.getLength(); i<max; i++) {
229                 Attr attr = (Attr) nnm.item(i);
230                 print (out, inset+" "+attr.getName()+":"+attr.getValue());
231             }
232             print (out, inset+" /end attr");
233         }
234         print (out, inset+" children:"+(node.hasChildNodes() ? "" : " (n/a)"));
235         if (node.hasChildNodes()) {
236             NodeList nl = node.getChildNodes();
237             for (int i=0,max=nl.getLength(); i<max; i++) {
238                 printStackTrace(nl.item(i), out, depth+2);
239             }
240             print (out, inset+" /end children");
241         }
242         print (out, inset+"/end @" + Integer.toHexString(node.hashCode()));
243         if (out!=null) try {out.flush();} catch (IOException ioe) {}
244     }
245     
246
247     protected static void print(OutputStream out, String JavaDoc s) {
248         if (out!=null) try {
249             out.write(s.getBytes());
250             out.write(sep);
251         } catch (IOException ioe) {}
252     }
253
254     public static void printMarkup(Node node) {
255         printMarkup(node, new PrintWriter(System.out, true), true, true, 0);
256     }
257
258     public static void printMarkup(Node node, PrintWriter out, boolean isHtml, boolean skipComments, int depth) {
259         if (depth<0) depth = 0;
260         if (depth>35) depth = 35;
261         String JavaDoc spaces = " ";
262         String JavaDoc inset = spaces.substring(0,depth*2);
263
264         //element
265
if (node instanceof Element) {
266             Element el = (Element) node;
267             out.print(inset+"<"+el.getTagName());
268             String JavaDoc sep = " ";
269             NamedNodeMap nnm = el.getAttributes();
270             for (int i=0, max=nnm.getLength(); i<max; i++) {
271                 Attr attr = (Attr) nnm.item(i);
272                 out.print(sep+attr.getName()+"=\""+attr.getValue()+"\"");
273             }
274             out.println(">"+" {@"+Integer.toHexString(node.hashCode())+"}");
275         
276             //print the children
277
printChildMarkup(node, out, isHtml, skipComments, depth);
278         
279             //print the closing tag (if it's not forbidden, as the given html tags are)
280
String JavaDoc tag = el.getTagName().toLowerCase();
281             if (!isHtml ||
282                (!tag.equals("area") && !tag.equals("base") && !tag.equals("basefont") &&
283                 !tag.equals("br") && !tag.equals("col") && !tag.equals("frame") &&
284                 !tag.equals("hr") && !tag.equals("image") && !tag.equals("input") &&
285                 !tag.equals("isindex") && !tag.equals("link") && !tag.equals("meta") &&
286                 !tag.equals("param"))) {
287                 out.println(inset+"</"+el.getTagName()+">");
288             }
289         
290         //character data
291
} else if (node instanceof CharacterData) {
292             if (node instanceof Comment) {
293                 if (!skipComments) {
294                     out.println(inset+"<!-- "+((CharacterData) node).getData()+" -->");
295                 }
296             } else {
297                 out.println(inset+((CharacterData) node).getData());
298             }
299
300         //node with child nodes
301
} else if (node.hasChildNodes()) {
302             printChildMarkup(node, out, isHtml, skipComments, depth);
303
304         //anything else
305
} else {
306             System.out.println("Unhandled element:"+node.getClass().getName());
307             org.enhydra.barracuda.plankton.data.CollectionsUtil.printStackTrace(Classes.getAllInterfaces(node));
308         }
309     }
310     
311     protected static void printChildMarkup(Node node, PrintWriter out, boolean isHtml, boolean skipComments, int depth) {
312         Node child = node.getFirstChild();
313         if (child==null) return;
314         do {
315             printMarkup(child, out, isHtml, skipComments, depth+1);
316             child = child.getNextSibling();
317         } while (child!=null);
318     }
319
320
321 }
322
Popular Tags