KickJava   Java API By Example, From Geeks To Geeks.

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


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.HashMap JavaDoc;
57 import java.util.List JavaDoc;
58 import java.util.Map JavaDoc;
59 import java.util.WeakHashMap JavaDoc;
60
61 import org.jaxen.NamespaceContext;
62
63 import freemarker.template.TemplateModelException;
64
65 /**
66  * @version $Id: Navigator.java,v 1.4 2003/01/31 11:39:17 szegedia Exp $
67  * @author Attila Szegedi
68  */

69 abstract class Navigator {
70     // Cache of already parsed XPath expressions
71
private final Map JavaDoc xpathCache = new WeakHashMap JavaDoc();
72     // Operators this navigator defines
73
private final Map JavaDoc operators = createOperatorMap();
74     private final NodeOperator attributeOperator = getOperator("_attributes");
75     private final NodeOperator childrenOperator = getOperator("_children");
76     
77     NodeOperator getOperator(String JavaDoc key) {
78         return (NodeOperator)operators.get(key);
79     }
80     
81     NodeOperator getAttributeOperator() {
82         return attributeOperator;
83     }
84     
85     NodeOperator getChildrenOperator() {
86         return childrenOperator;
87     }
88     
89     abstract void getAsString(Object JavaDoc node, StringWriter JavaDoc sw)
90     throws
91         TemplateModelException;
92
93     List JavaDoc applyXPath(List JavaDoc nodes, String JavaDoc xpathString, Object JavaDoc namespaces)
94     throws
95         TemplateModelException
96     {
97         XPathEx xpath = null;
98         try
99         {
100             synchronized(xpathCache)
101             {
102                 xpath = (XPathEx)xpathCache.get(xpathString);
103                 if (xpath == null)
104                 {
105                     xpath = createXPathEx(xpathString);
106                     xpathCache.put(xpathString, xpath);
107                 }
108             }
109             return xpath.selectNodes(nodes, (NamespaceContext)namespaces);
110         }
111         catch(Exception JavaDoc e)
112         {
113             throw new TemplateModelException("Could not evaulate XPath expression " + xpathString, e);
114         }
115     }
116     
117     interface XPathEx
118     {
119         List JavaDoc selectNodes(Object JavaDoc nodes, NamespaceContext namespaces) throws TemplateModelException;
120     }
121     
122     abstract XPathEx createXPathEx(String JavaDoc xpathString) throws TemplateModelException;
123
124     abstract void getChildren(Object JavaDoc node, String JavaDoc localName, String JavaDoc namespaceUri, List JavaDoc result);
125     
126     abstract void getAttributes(Object JavaDoc node, String JavaDoc localName, String JavaDoc namespaceUri, List JavaDoc result);
127
128     abstract void getDescendants(Object JavaDoc node, List JavaDoc result);
129
130     abstract Object JavaDoc getParent(Object JavaDoc node);
131     
132     abstract Object JavaDoc getDocument(Object JavaDoc node);
133     
134     abstract Object JavaDoc getDocumentType(Object JavaDoc node);
135
136     private void getAncestors(Object JavaDoc node, List JavaDoc result)
137     {
138         for(;;) {
139             Object JavaDoc parent = getParent(node);
140             if(parent == null) {
141                 break;
142             }
143             result.add(parent);
144             node = parent;
145         }
146     }
147     
148     abstract void getContent(Object JavaDoc node, List JavaDoc result);
149
150     abstract String JavaDoc getText(Object JavaDoc node);
151
152     abstract String JavaDoc getLocalName(Object JavaDoc node);
153
154     abstract String JavaDoc getNamespacePrefix(Object JavaDoc node);
155
156     String JavaDoc getQualifiedName(Object JavaDoc node) {
157         String JavaDoc lname = getLocalName(node);
158         if(lname == null) {
159             return null;
160         }
161         String JavaDoc nsprefix = getNamespacePrefix(node);
162         if(nsprefix == null || nsprefix.length() == 0) {
163             return lname;
164         }
165         else {
166             return nsprefix + ":" + lname;
167         }
168     }
169     
170     abstract String JavaDoc getType(Object JavaDoc node);
171
172     abstract String JavaDoc getNamespaceUri(Object JavaDoc node);
173
174     boolean equal(String JavaDoc s1, String JavaDoc s2) {
175         return s1 == null ? s2 == null : s1.equals(s2);
176     }
177     
178     private Map JavaDoc createOperatorMap() {
179         Map JavaDoc map = new HashMap JavaDoc();
180         map.put("_attributes", new AttributesOp());
181         map.put("@*", map.get("_attributes"));
182         map.put("_children", new ChildrenOp());
183         map.put("*", map.get("_children"));
184         map.put("_descendantOrSelf", new DescendantOrSelfOp());
185         map.put("_descendant", new DescendantOp());
186         map.put("_document", new DocumentOp());
187         map.put("_doctype", new DocumentTypeOp());
188         map.put("_ancestor", new AncestorOp());
189         map.put("_ancestorOrSelf", new AncestorOrSelfOp());
190         map.put("_content", new ContentOp());
191         map.put("_name", new LocalNameOp());
192         map.put("_nsprefix", new NamespacePrefixOp());
193         map.put("_nsuri", new NamespaceUriOp());
194         map.put("_parent", new ParentOp());
195         map.put("_qname", new QualifiedNameOp());
196         map.put("_text", new TextOp());
197         map.put("_type", new TypeOp());
198         return map;
199     }
200
201     private class ChildrenOp implements NodeOperator {
202         public void process(Object JavaDoc node, String JavaDoc localName, String JavaDoc namespaceUri, List JavaDoc result)
203         {
204             getChildren(node, localName, namespaceUri, result);
205         }
206     }
207
208     private class AttributesOp implements NodeOperator {
209         public void process(Object JavaDoc node, String JavaDoc localName, String JavaDoc namespaceUri, List JavaDoc result)
210         {
211             getAttributes(node, localName, namespaceUri, result);
212         }
213     }
214
215     private class DescendantOrSelfOp implements NodeOperator {
216         public void process(Object JavaDoc node, String JavaDoc localName, String JavaDoc namespaceUri, List JavaDoc result)
217         {
218             result.add(node);
219             getDescendants(node, result);
220         }
221     }
222
223     private class DescendantOp implements NodeOperator {
224         public void process(Object JavaDoc node, String JavaDoc localName, String JavaDoc namespaceUri, List JavaDoc result)
225         {
226             getDescendants(node, result);
227         }
228     }
229
230     private class AncestorOrSelfOp implements NodeOperator {
231         public void process(Object JavaDoc node, String JavaDoc localName, String JavaDoc namespaceUri, List JavaDoc result)
232         {
233             result.add(node);
234             getAncestors(node, result);
235         }
236     }
237
238     private class AncestorOp implements NodeOperator {
239         public void process(Object JavaDoc node, String JavaDoc localName, String JavaDoc namespaceUri, List JavaDoc result)
240         {
241             getAncestors(node, result);
242         }
243     }
244
245     private class ParentOp implements NodeOperator {
246         public void process(Object JavaDoc node, String JavaDoc localName, String JavaDoc namespaceUri, List JavaDoc result)
247         {
248             Object JavaDoc parent = getParent(node);
249             if(parent != null) {
250                 result.add(parent);
251             }
252         }
253     }
254
255     private class DocumentOp implements NodeOperator {
256         public void process(Object JavaDoc node, String JavaDoc localName, String JavaDoc namespaceUri, List JavaDoc result)
257         {
258             Object JavaDoc document = getDocument(node);
259             if(document != null) {
260                 result.add(document);
261             }
262         }
263     }
264
265     private class DocumentTypeOp implements NodeOperator {
266         public void process(Object JavaDoc node, String JavaDoc localName, String JavaDoc namespaceUri, List JavaDoc result)
267         {
268             Object JavaDoc documentType = getDocumentType(node);
269             if(documentType != null) {
270                 result.add(documentType);
271             }
272         }
273     }
274
275     private class ContentOp implements NodeOperator {
276         public void process(Object JavaDoc node, String JavaDoc localName, String JavaDoc namespaceUri, List JavaDoc result)
277         {
278             getContent(node, result);
279         }
280     }
281
282     private class TextOp implements NodeOperator {
283         public void process(Object JavaDoc node, String JavaDoc localName, String JavaDoc namespaceUri, List JavaDoc result)
284         {
285             String JavaDoc text = getText(node);
286             if(text != null) {
287                 result.add(text);
288             }
289         }
290     }
291
292     private class LocalNameOp implements NodeOperator {
293         public void process(Object JavaDoc node, String JavaDoc localName, String JavaDoc namespaceUri, List JavaDoc result)
294         {
295             String JavaDoc text = getLocalName(node);
296             if(text != null) {
297                 result.add(text);
298             }
299         }
300     }
301
302     private class QualifiedNameOp implements NodeOperator {
303         public void process(Object JavaDoc node, String JavaDoc localName, String JavaDoc namespaceUri, List JavaDoc result)
304         {
305             String JavaDoc qname = getQualifiedName(node);
306             if(qname != null) {
307                 result.add(qname);
308             }
309         }
310     }
311
312     private class NamespacePrefixOp implements NodeOperator {
313         public void process(Object JavaDoc node, String JavaDoc localName, String JavaDoc namespaceUri, List JavaDoc result)
314         {
315             String JavaDoc text = getNamespacePrefix(node);
316             if(text != null) {
317                 result.add(text);
318             }
319         }
320     }
321
322     private class NamespaceUriOp implements NodeOperator {
323         public void process(Object JavaDoc node, String JavaDoc localName, String JavaDoc namespaceUri, List JavaDoc result)
324         {
325             String JavaDoc text = getNamespaceUri(node);
326             if(text != null) {
327                 result.add(text);
328             }
329         }
330     }
331
332     private class TypeOp implements NodeOperator {
333         public void process(Object JavaDoc node, String JavaDoc localName, String JavaDoc namespaceUri, List JavaDoc result)
334         {
335             result.add(getType(node));
336         }
337     }
338 }
339
Popular Tags