KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > freemarker > ext > xml > DomNavigator


1 /*
2  * Copyright (c) 2003 The Visigoth Software Society. All rights
3  * reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  *
9  * 1. Redistributions of source code must retain the above copyright
10  * notice, this list of conditions and the following disclaimer.
11  *
12  * 2. Redistributions in binary form must reproduce the above copyright
13  * notice, this list of conditions and the following disclaimer in
14  * the documentation and/or other materials provided with the
15  * distribution.
16  *
17  * 3. The end-user documentation included with the redistribution, if
18  * any, must include the following acknowledgement:
19  * "This product includes software developed by the
20  * Visigoth Software Society (http://www.visigoths.org/)."
21  * Alternately, this acknowledgement may appear in the software itself,
22  * if and wherever such third-party acknowledgements normally appear.
23  *
24  * 4. Neither the name "FreeMarker", "Visigoth", nor any of the names of the
25  * project contributors may be used to endorse or promote products derived
26  * from this software without prior written permission. For written
27  * permission, please contact visigoths@visigoths.org.
28  *
29  * 5. Products derived from this software may not be called "FreeMarker" or "Visigoth"
30  * nor may "FreeMarker" or "Visigoth" appear in their names
31  * without prior written permission of the Visigoth Software Society.
32  *
33  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
34  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
35  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
36  * DISCLAIMED. IN NO EVENT SHALL THE VISIGOTH SOFTWARE SOCIETY OR
37  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
38  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
39  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
40  * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
41  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
42  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
43  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
44  * SUCH DAMAGE.
45  * ====================================================================
46  *
47  * This software consists of voluntary contributions made by many
48  * individuals on behalf of the Visigoth Software Society. For more
49  * information on the Visigoth Software Society, please see
50  * http://www.visigoths.org/
51  */

52
53 package freemarker.ext.xml;
54
55 import java.io.StringWriter JavaDoc;
56 import java.util.List JavaDoc;
57
58 import org.jaxen.Context;
59 import org.jaxen.NamespaceContext;
60 import org.jaxen.dom.DOMXPath;
61 import org.w3c.dom.Attr JavaDoc;
62 import org.w3c.dom.Document JavaDoc;
63 import org.w3c.dom.DocumentType JavaDoc;
64 import org.w3c.dom.Element JavaDoc;
65 import org.w3c.dom.NamedNodeMap JavaDoc;
66 import org.w3c.dom.Node JavaDoc;
67 import org.w3c.dom.NodeList JavaDoc;
68 import org.w3c.dom.ProcessingInstruction JavaDoc;
69 import org.w3c.dom.Text JavaDoc;
70 import freemarker.template.TemplateModelException;
71 import freemarker.template.utility.StringUtil;
72
73 /**
74  * @version $Id: DomNavigator.java,v 1.8 2003/09/02 09:54:59 szegedia Exp $
75  * @author Attila Szegedi
76  */

77 class DomNavigator extends Navigator {
78     DomNavigator() {
79     }
80
81     void getAsString(Object JavaDoc node, StringWriter JavaDoc sw) {
82         outputContent((Node JavaDoc)node, sw.getBuffer());
83     }
84     
85     private void outputContent(Node JavaDoc n, StringBuffer JavaDoc buf) {
86         switch(n.getNodeType()) {
87             case Node.ATTRIBUTE_NODE: {
88                 buf.append(' ')
89                    .append(getQualifiedName(n))
90                    .append("=\"")
91                    .append(StringUtil.XMLEncNA(n.getNodeValue())) // XmlEncNA for HTML compatibility
92
.append('"');
93                 break;
94             }
95             case Node.CDATA_SECTION_NODE: {
96                 buf.append("<![CDATA[").append(n.getNodeValue()).append("]]>");
97                 break;
98             }
99             case Node.COMMENT_NODE: {
100                 buf.append("<!--").append(n.getNodeValue()).append("-->");
101                 break;
102             }
103             case Node.DOCUMENT_NODE: {
104                 outputContent(n.getChildNodes(), buf);
105                 break;
106             }
107             case Node.DOCUMENT_TYPE_NODE: {
108                 buf.append("<!DOCTYPE ").append(n.getNodeName());
109                 DocumentType JavaDoc dt = (DocumentType JavaDoc)n;
110                 if(dt.getPublicId() != null) {
111                     buf.append(" PUBLIC \"").append(dt.getPublicId()).append('"');
112                 }
113                 if(dt.getSystemId() != null) {
114                     buf.append('"').append(dt.getSystemId()).append('"');
115                 }
116                 if(dt.getInternalSubset() != null) {
117                     buf.append(" [").append(dt.getInternalSubset()).append(']');
118                 }
119                 buf.append('>');
120                 break;
121             }
122             case Node.ELEMENT_NODE: {
123                 buf.append('<').append(getQualifiedName(n));
124                 outputContent(n.getAttributes(), buf);
125                 buf.append('>');
126                 outputContent(n.getChildNodes(), buf);
127                 buf.append("</").append(getQualifiedName(n)).append('>');
128                 break;
129             }
130             case Node.ENTITY_NODE: {
131                 outputContent(n.getChildNodes(), buf);
132                 break;
133             }
134             case Node.ENTITY_REFERENCE_NODE: {
135                 buf.append('&').append(n.getNodeName()).append(';');
136                 break;
137             }
138             case Node.PROCESSING_INSTRUCTION_NODE: {
139                 buf.append("<?").append(n.getNodeName()).append(' ').append(n.getNodeValue()).append("?>");
140                 break;
141             }
142             case Node.TEXT_NODE: {
143                 buf.append(StringUtil.XMLEncNQG(n.getNodeValue()));
144                 break;
145             }
146         }
147     }
148
149     private void outputContent(NodeList JavaDoc nodes, StringBuffer JavaDoc buf) {
150         for(int i = 0; i < nodes.getLength(); ++i) {
151             outputContent(nodes.item(i), buf);
152         }
153     }
154     
155     private void outputContent(NamedNodeMap JavaDoc nodes, StringBuffer JavaDoc buf) {
156         for(int i = 0; i < nodes.getLength(); ++i) {
157             outputContent(nodes.item(i), buf);
158         }
159     }
160     
161     void getChildren(Object JavaDoc node, String JavaDoc localName, String JavaDoc namespaceUri, List JavaDoc result) {
162         if("".equals(namespaceUri)) {
163             namespaceUri = null;
164         }
165         NodeList JavaDoc children = ((Node JavaDoc)node).getChildNodes();
166         for(int i = 0; i < children.getLength(); ++i) {
167             Node JavaDoc subnode = children.item(i);
168             // IMO, we should get the text nodes as well -- will discuss.
169
if(subnode.getNodeType() == Node.ELEMENT_NODE || subnode.getNodeType() == Node.TEXT_NODE) {
170                 if(localName == null || (equal(subnode.getNodeName(), localName) && equal(subnode.getNamespaceURI(), namespaceUri))) {
171                     result.add(subnode);
172                 }
173             }
174         }
175     }
176     
177     void getAttributes(Object JavaDoc node, String JavaDoc localName, String JavaDoc namespaceUri, List JavaDoc result) {
178         if(node instanceof Element JavaDoc) {
179             Element JavaDoc e = (Element JavaDoc)node;
180             if(localName == null) {
181                 NamedNodeMap JavaDoc atts = e.getAttributes();
182                 for(int i = 0; i < atts.getLength(); ++i) {
183                     result.add(atts.item(i));
184                 }
185             }
186             else {
187                 if("".equals(namespaceUri)) {
188                     namespaceUri = null;
189                 }
190                 Attr JavaDoc attr = e.getAttributeNodeNS(namespaceUri, localName);
191                 if(attr != null) {
192                     result.add(attr);
193                 }
194             }
195         }
196         else if (node instanceof ProcessingInstruction JavaDoc) {
197             ProcessingInstruction JavaDoc pi = (ProcessingInstruction JavaDoc)node;
198             if ("target".equals(localName)) {
199                 result.add(createAttribute(pi, "target", pi.getTarget()));
200             }
201             else if ("data".equals(localName)) {
202                 result.add(createAttribute(pi, "data", pi.getData()));
203             }
204             else {
205                 // TODO: DOM has no facility for parsing data into
206
// name-value pairs...
207
;
208             }
209         } else if (node instanceof DocumentType JavaDoc) {
210             DocumentType JavaDoc doctype = (DocumentType JavaDoc)node;
211             if ("publicId".equals(localName)) {
212                 result.add(createAttribute(doctype, "publicId", doctype.getPublicId()));
213             }
214             else if ("systemId".equals(localName)) {
215                 result.add(createAttribute(doctype, "systemId", doctype.getSystemId()));
216             }
217             else if ("elementName".equals(localName)) {
218                 result.add(createAttribute(doctype, "elementName", doctype.getNodeName()));
219             }
220         }
221     }
222
223     private Attr JavaDoc createAttribute(Node JavaDoc node, String JavaDoc name, String JavaDoc value) {
224         Attr JavaDoc attr = node.getOwnerDocument().createAttribute(name);
225         attr.setNodeValue(value);
226         return attr;
227     }
228     
229     void getDescendants(Object JavaDoc node, List JavaDoc result) {
230         NodeList JavaDoc children = ((Node JavaDoc)node).getChildNodes();
231         for(int i = 0; i < children.getLength(); ++i) {
232             Node JavaDoc subnode = children.item(i);
233             if(subnode.getNodeType() == Node.ELEMENT_NODE) {
234                 result.add(subnode);
235                 getDescendants(subnode, result);
236             }
237         }
238     }
239
240     Object JavaDoc getParent(Object JavaDoc node) {
241         return ((Node JavaDoc)node).getParentNode();
242     }
243
244     Object JavaDoc getDocument(Object JavaDoc node) {
245         return ((Node JavaDoc)node).getOwnerDocument();
246     }
247
248     Object JavaDoc getDocumentType(Object JavaDoc node) {
249         return
250             node instanceof Document JavaDoc
251             ? ((Document JavaDoc)node).getDoctype()
252             : null;
253     }
254
255     void getContent(Object JavaDoc node, List JavaDoc result) {
256         NodeList JavaDoc children = ((Node JavaDoc)node).getChildNodes();
257         for(int i = 0; i < children.getLength(); ++i) {
258             result.add(children.item(i));
259         }
260     }
261
262     String JavaDoc getText(Object JavaDoc node) {
263         StringBuffer JavaDoc buf = new StringBuffer JavaDoc();
264         if(node instanceof Element JavaDoc) {
265             NodeList JavaDoc children = ((Node JavaDoc)node).getChildNodes();
266             for(int i = 0; i < children.getLength(); ++i) {
267                 Node JavaDoc child = children.item(i);
268                 if(child instanceof Text JavaDoc) {
269                     buf.append(child.getNodeValue());
270                 }
271             }
272             return buf.toString();
273         }
274         else {
275             return ((Node JavaDoc)node).getNodeValue();
276         }
277     }
278
279     String JavaDoc getLocalName(Object JavaDoc node) {
280         return ((Node JavaDoc)node).getNodeName();
281     }
282
283     String JavaDoc getNamespacePrefix(Object JavaDoc node) {
284         return ((Node JavaDoc)node).getPrefix();
285     }
286
287     String JavaDoc getNamespaceUri(Object JavaDoc node) {
288         return ((Node JavaDoc)node).getNamespaceURI();
289     }
290
291     String JavaDoc getType(Object JavaDoc node) {
292         switch(((Node JavaDoc)node).getNodeType()) {
293             case Node.ATTRIBUTE_NODE: {
294                 return "attribute";
295             }
296             case Node.CDATA_SECTION_NODE: {
297                 return "cdata";
298             }
299             case Node.COMMENT_NODE: {
300                 return "comment";
301             }
302             case Node.DOCUMENT_NODE: {
303                 return "document";
304             }
305             case Node.DOCUMENT_TYPE_NODE: {
306                 return "documentType";
307             }
308             case Node.ELEMENT_NODE: {
309                 return "element";
310             }
311             case Node.ENTITY_NODE: {
312                 return "entity";
313             }
314             case Node.ENTITY_REFERENCE_NODE: {
315                 return "entityReference";
316             }
317             case Node.PROCESSING_INSTRUCTION_NODE: {
318                 return "processingInstruction";
319             }
320             case Node.TEXT_NODE: {
321                 return "text";
322             }
323         }
324         return "unknown";
325     }
326
327     XPathEx createXPathEx(String JavaDoc xpathString) throws TemplateModelException
328     {
329         try {
330             return new DomXPathEx(xpathString);
331         }
332         catch(Exception JavaDoc e) {
333             throw new TemplateModelException(e);
334         }
335     }
336
337     private static final class DomXPathEx
338     extends
339         DOMXPath
340     implements
341         XPathEx
342     {
343         DomXPathEx(String JavaDoc path)
344         throws
345             Exception JavaDoc
346         {
347             super(path);
348         }
349
350         public List JavaDoc selectNodes(Object JavaDoc object, NamespaceContext namespaces)
351         throws
352             TemplateModelException
353         {
354             Context context = getContext(object);
355             context.getContextSupport().setNamespaceContext(namespaces);
356             try {
357                 return selectNodesForContext(context);
358             }
359             catch(Exception JavaDoc e) {
360                 throw new TemplateModelException(e);
361             }
362         }
363     }
364 }
365
Popular Tags