KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > batik > dom > util > DOMUtilities


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

18 package org.apache.batik.dom.util;
19
20 import java.io.IOException JavaDoc;
21 import java.io.Writer JavaDoc;
22
23 import org.apache.batik.xml.XMLUtilities;
24 import org.w3c.dom.Attr JavaDoc;
25 import org.w3c.dom.DOMException JavaDoc;
26 import org.w3c.dom.DOMImplementation JavaDoc;
27 import org.w3c.dom.Document JavaDoc;
28 import org.w3c.dom.DocumentType JavaDoc;
29 import org.w3c.dom.Element JavaDoc;
30 import org.w3c.dom.NamedNodeMap JavaDoc;
31 import org.w3c.dom.Node JavaDoc;
32
33 /**
34  * A collection of utility functions for the DOM.
35  *
36  * @author <a HREF="mailto:stephane@hillion.org">Stephane Hillion</a>
37  * @version $Id: DOMUtilities.java,v 1.13 2005/02/22 09:13:02 cam Exp $
38  */

39 public class DOMUtilities extends XMLUtilities {
40     /**
41      * Do not need to be instantiated.
42      */

43     protected DOMUtilities() {
44     }
45
46     /**
47      * Writes the given document using the given writer.
48      */

49     public static void writeDocument(Document JavaDoc doc, Writer JavaDoc w) throws IOException JavaDoc {
50         for (Node JavaDoc n = doc.getFirstChild();
51              n != null;
52              n = n.getNextSibling()) {
53             writeNode(n, w);
54         }
55     }
56
57     /**
58      * Writes a node using the given writer.
59      */

60     public static void writeNode(Node JavaDoc n, Writer JavaDoc w) throws IOException JavaDoc {
61         switch (n.getNodeType()) {
62         case Node.ELEMENT_NODE:
63             w.write("<");
64             w.write(n.getNodeName());
65
66             if (n.hasAttributes()) {
67                 NamedNodeMap JavaDoc attr = n.getAttributes();
68                 int len = attr.getLength();
69                 for (int i = 0; i < len; i++) {
70                     Attr JavaDoc a = (Attr JavaDoc)attr.item(i);
71                     w.write(" ");
72                     w.write(a.getNodeName());
73                     w.write("=\"");
74                     w.write(contentToString(a.getNodeValue()));
75                     w.write("\"");
76                 }
77             }
78
79             Node JavaDoc c = n.getFirstChild();
80             if (c != null) {
81                 w.write(">");
82                 for (; c != null;
83                      c = c.getNextSibling()) {
84                     writeNode(c, w);
85                 }
86                 w.write("</");
87                 w.write(n.getNodeName());
88                 w.write(">");
89             } else {
90                 w.write("/>");
91             }
92             break;
93         case Node.TEXT_NODE:
94             w.write(contentToString(n.getNodeValue()));
95             break;
96         case Node.CDATA_SECTION_NODE:
97             w.write("<![CDATA[");
98             w.write(n.getNodeValue());
99             w.write("]]>");
100             break;
101         case Node.ENTITY_REFERENCE_NODE:
102             w.write("&");
103             w.write(n.getNodeName());
104             w.write(";");
105             break;
106         case Node.PROCESSING_INSTRUCTION_NODE:
107             w.write("<?");
108             w.write(n.getNodeName());
109             // TD: Bug #19392
110
w.write(" ");
111             w.write(n.getNodeValue());
112             w.write("?>");
113             break;
114         case Node.COMMENT_NODE:
115             w.write("<!--");
116             w.write(n.getNodeValue());
117             w.write("-->");
118             break;
119         case Node.DOCUMENT_TYPE_NODE: {
120             DocumentType JavaDoc dt = (DocumentType JavaDoc)n;
121             w.write ("<!DOCTYPE ");
122             w.write (n.getOwnerDocument().getDocumentElement().getNodeName());
123             String JavaDoc pubID = dt.getPublicId();
124             if (pubID != null) {
125                 w.write (" PUBLIC \"" + dt.getNodeName() + "\" \"" +
126                            pubID + "\">");
127             } else {
128                 String JavaDoc sysID = dt.getSystemId();
129                 if (sysID != null)
130                     w.write (" SYSTEM \"" + sysID + "\">");
131             }
132         }
133             break;
134         default:
135             throw new Error JavaDoc("Internal error (" + n.getNodeType() + ")");
136         }
137     }
138
139     /**
140      * Returns the given content value transformed to replace invalid
141      * characters with entities.
142      */

143     public static String JavaDoc contentToString(String JavaDoc s) {
144         StringBuffer JavaDoc result = new StringBuffer JavaDoc();
145
146         for (int i = 0; i < s.length(); i++) {
147             char c = s.charAt(i);
148
149             switch (c) {
150             case '<':
151                 result.append("&lt;");
152                 break;
153             case '>':
154                 result.append("&gt;");
155                 break;
156             case '&':
157                 result.append("&amp;");
158                 break;
159             case '"':
160                 result.append("&quot;");
161                 break;
162             case '\'':
163                 result.append("&apos;");
164                 break;
165             default:
166                 result.append(c);
167             }
168         }
169         
170         return result.toString();
171     }
172
173     /**
174      * Deep clones a document using the given DOM implementation.
175      */

176     public static Document JavaDoc deepCloneDocument(Document JavaDoc doc, DOMImplementation JavaDoc impl) {
177         Element JavaDoc root = doc.getDocumentElement();
178         Document JavaDoc result = impl.createDocument(root.getNamespaceURI(),
179                                               root.getNodeName(),
180                                               null);
181         Element JavaDoc rroot = result.getDocumentElement();
182         boolean before = true;
183         for (Node JavaDoc n = doc.getFirstChild(); n != null; n = n.getNextSibling()) {
184             if (n == root) {
185                 before = false;
186                 if (root.hasAttributes()) {
187                     NamedNodeMap JavaDoc attr = root.getAttributes();
188                     int len = attr.getLength();
189                     for (int i = 0; i < len; i++) {
190                         rroot.setAttributeNode((Attr JavaDoc)result.importNode(attr.item(i),
191                                                                        true));
192                     }
193                 }
194                 for (Node JavaDoc c = root.getFirstChild();
195                      c != null;
196                      c = c.getNextSibling()) {
197                     rroot.appendChild(result.importNode(c, true));
198                 }
199             } else {
200                 if (n.getNodeType() != Node.DOCUMENT_TYPE_NODE) {
201                     if (before) {
202                         result.insertBefore(result.importNode(n, true), rroot);
203                     } else {
204                         result.appendChild(result.importNode(n, true));
205                     }
206                 }
207             }
208         }
209         return result;
210     }
211
212     /**
213      * Tests whether the given string is a valid name.
214      */

215     public static boolean isValidName(String JavaDoc s) {
216     char c = s.charAt(0);
217         int d = c / 32;
218         int m = c % 32;
219     if ((NAME_FIRST_CHARACTER[d] & (1 << m)) == 0) {
220         return false;
221     }
222     int len = s.length();
223     for (int i = 1; i < len; i++) {
224         c = s.charAt(i);
225         d = c / 32;
226         m = c % 32;
227         if ((NAME_CHARACTER[d] & (1 << m)) == 0) {
228         return false;
229         }
230     }
231     return true;
232     }
233     
234     /**
235      * Tests whether the given string is a valid prefix.
236      * This method assume that isValidName(s) is true.
237      */

238     public static boolean isValidPrefix(String JavaDoc s) {
239     return s.indexOf(':') == -1;
240     }
241
242     /**
243      * Gets the prefix from the given qualified name.
244      * This method assume that isValidName(s) is true.
245      */

246     public static String JavaDoc getPrefix(String JavaDoc s) {
247     int i = s.indexOf(':');
248     return (i == -1 || i == s.length()-1)
249         ? null
250         : s.substring(0, i);
251     }
252     
253     /**
254      * Gets the local name from the given qualified name.
255      * This method assume that isValidName(s) is true.
256      */

257     public static String JavaDoc getLocalName(String JavaDoc s) {
258     int i = s.indexOf(':');
259     return (i == -1 || i == s.length()-1)
260         ? s
261         : s.substring(i + 1);
262     }
263
264     /**
265      * Parses a 'xml-stylesheet' processing instruction data section and
266      * puts the pseudo attributes in the given table.
267      */

268     public static void parseStyleSheetPIData(String JavaDoc data, HashTable table) {
269         // !!! Internationalization
270
char c;
271     int i = 0;
272     // Skip leading whitespaces
273
while (i < data.length()) {
274         c = data.charAt(i);
275         if (!XMLUtilities.isXMLSpace(c)) {
276         break;
277         }
278         i++;
279     }
280     while (i < data.length()) {
281         // Parse the pseudo attribute name
282
c = data.charAt(i);
283         int d = c / 32;
284         int m = c % 32;
285         if ((NAME_FIRST_CHARACTER[d] & (1 << m)) == 0) {
286         throw new DOMException JavaDoc(DOMException.INVALID_CHARACTER_ERR,
287                        "Wrong name initial: " + c);
288         }
289         StringBuffer JavaDoc ident = new StringBuffer JavaDoc();
290         ident.append(c);
291         while (++i < data.length()) {
292         c = data.charAt(i);
293         d = c / 32;
294         m = c % 32;
295         if ((NAME_CHARACTER[d] & (1 << m)) == 0) {
296             break;
297         }
298         ident.append(c);
299         }
300         if (i >= data.length()) {
301         throw new DOMException JavaDoc(DOMException.SYNTAX_ERR,
302                        "Wrong xml-stylesheet data: " + data);
303         }
304         // Skip whitespaces
305
while (i < data.length()) {
306         c = data.charAt(i);
307         if (!XMLUtilities.isXMLSpace(c)) {
308             break;
309         }
310         i++;
311         }
312         if (i >= data.length()) {
313         throw new DOMException JavaDoc(DOMException.SYNTAX_ERR,
314                        "Wrong xml-stylesheet data: " + data);
315         }
316         // The next char must be '='
317
if (data.charAt(i) != '=') {
318         throw new DOMException JavaDoc(DOMException.SYNTAX_ERR,
319                        "Wrong xml-stylesheet data: " + data);
320         }
321         i++;
322         // Skip whitespaces
323
while (i < data.length()) {
324         c = data.charAt(i);
325         if (!XMLUtilities.isXMLSpace(c)) {
326             break;
327         }
328         i++;
329         }
330         if (i >= data.length()) {
331         throw new DOMException JavaDoc(DOMException.SYNTAX_ERR,
332                        "Wrong xml-stylesheet data: " + data);
333         }
334         // The next char must be '\'' or '"'
335
c = data.charAt(i);
336         i++;
337         StringBuffer JavaDoc value = new StringBuffer JavaDoc();
338         if (c == '\'') {
339         while (i < data.length()) {
340             c = data.charAt(i);
341             if (c == '\'') {
342             break;
343             }
344             value.append(c);
345             i++;
346         }
347         if (i >= data.length()) {
348             throw new DOMException JavaDoc(DOMException.SYNTAX_ERR,
349                        "Wrong xml-stylesheet data: " +
350                                            data);
351         }
352         } else if (c == '"') {
353         while (i < data.length()) {
354             c = data.charAt(i);
355             if (c == '"') {
356             break;
357             }
358             value.append(c);
359             i++;
360         }
361         if (i >= data.length()) {
362             throw new DOMException JavaDoc(DOMException.SYNTAX_ERR,
363                        "Wrong xml-stylesheet data: " +
364                                            data);
365         }
366         } else {
367         throw new DOMException JavaDoc(DOMException.SYNTAX_ERR,
368                        "Wrong xml-stylesheet data: " + data);
369         }
370         table.put(ident.toString().intern(), value.toString());
371         i++;
372         // Skip whitespaces
373
while (i < data.length()) {
374         c = data.charAt(i);
375         if (!XMLUtilities.isXMLSpace(c)) {
376             break;
377         }
378         i++;
379         }
380     }
381     }
382 }
383
Popular Tags