KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > freemarker > ext > dom > NodeListModel


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.dom;
54
55 import freemarker.template.*;
56 import freemarker.template.utility.StringUtil;
57 import freemarker.core.Environment;
58 import org.w3c.dom.*;
59 import java.util.List JavaDoc;
60 import java.util.ArrayList JavaDoc;
61
62 class NodeListModel extends SimpleSequence implements TemplateHashModel {
63     
64     NodeModel contextNode;
65     XPathSupport xpathSupport;
66     
67     private static ObjectWrapper nodeWrapper = new ObjectWrapper() {
68         public TemplateModel wrap(Object JavaDoc obj) {
69             if (obj instanceof NodeModel) {
70                 return (NodeModel) obj;
71             }
72             return NodeModel.wrap((Node) obj);
73         }
74     };
75     
76     
77     NodeListModel(Node node) {
78         this(NodeModel.wrap(node));
79     }
80     
81     NodeListModel(NodeModel contextNode) {
82         super(nodeWrapper);
83         this.contextNode = contextNode;
84     }
85     
86     NodeListModel(NodeList nodeList, NodeModel contextNode) {
87         super(nodeWrapper);
88         for (int i=0; i<nodeList.getLength();i++) {
89             list.add(nodeList.item(i));
90         }
91         this.contextNode = contextNode;
92     }
93     
94     NodeListModel(NamedNodeMap nodeList, NodeModel contextNode) {
95         super(nodeWrapper);
96         for (int i=0; i<nodeList.getLength();i++) {
97             list.add(nodeList.item(i));
98         }
99         this.contextNode = contextNode;
100     }
101     
102     NodeListModel(List JavaDoc list, NodeModel contextNode) {
103         super(list, nodeWrapper);
104         this.contextNode = contextNode;
105     }
106     
107     NodeListModel filterByName(String JavaDoc name) throws TemplateModelException {
108         NodeListModel result = new NodeListModel(contextNode);
109         int size = size();
110         if (size == 0) {
111             return result;
112         }
113         Environment env = Environment.getCurrentEnvironment();
114         for (int i = 0; i<size; i++) {
115             NodeModel nm = (NodeModel) get(i);
116             if (nm instanceof ElementModel) {
117                 if (((ElementModel) nm).matchesName(name, env)) {
118                     result.add(nm);
119                 }
120             }
121         }
122         return result;
123     }
124     
125     public boolean isEmpty() {
126         return size() == 0;
127     }
128     
129     public TemplateModel get(String JavaDoc key) throws TemplateModelException {
130         if (size() ==1) {
131             NodeModel nm = (NodeModel) get(0);
132             return nm.get(key);
133         }
134         if (key.equals("@@markup")
135             || key.equals("@@nested_markup")
136             || key.equals("@@text"))
137         {
138             StringBuffer JavaDoc result = new StringBuffer JavaDoc();
139             for (int i=0; i<size(); i++) {
140                 NodeModel nm = (NodeModel) get(i);
141                 TemplateScalarModel textModel = (TemplateScalarModel) nm.get(key);
142                 result.append(textModel.getAsString());
143             }
144             return new SimpleScalar(result.toString());
145         }
146         if (StringUtil.isXMLID(key)
147             || ((key.startsWith("@") && StringUtil.isXMLID(key.substring(1))))
148             || key.equals("*") || key.equals("**") || key.equals("@@") || key.equals("@*"))
149         {
150             NodeListModel result = new NodeListModel(contextNode);
151             for (int i=0; i<size(); i++) {
152                 NodeModel nm = (NodeModel) get(i);
153                 if (nm instanceof ElementModel) {
154                     TemplateSequenceModel tsm = (TemplateSequenceModel) ((ElementModel) nm).get(key);
155                     int size = tsm == null ? 0 : tsm.size();
156                     for (int j=0; j < size; j++) {
157                         result.add(tsm.get(j));
158                     }
159                 }
160             }
161             if (result.size() == 1) {
162                 return result.get(0);
163             }
164             return result;
165         }
166         XPathSupport xps = getXPathSupport();
167         if (xps != null) {
168             Object JavaDoc context = (size() == 0) ? null : rawNodeList();
169             return xps.executeQuery(context, key);
170         }
171         throw new TemplateModelException("Key: '" + key + "' is not legal for a node sequence ("
172                 + this.getClass().getName() + "). This node sequence contains " + size() + " node(s). "
173                 + "Some keys are valid only for node sequences of size 1. "
174                 + "If you use Xalan (instead of Jaxen), XPath expression keys work only with "
175                 + "node lists of size 1.");
176     }
177     
178     private List JavaDoc rawNodeList() throws TemplateModelException {
179         int size = size();
180         ArrayList JavaDoc al = new ArrayList JavaDoc(size);
181         for (int i=0; i<size; i++) {
182             al.add(((NodeModel) get(i)).node);
183         }
184         return al;
185     }
186     
187     XPathSupport getXPathSupport() throws TemplateModelException {
188         if (xpathSupport == null) {
189             if (contextNode != null) {
190                 xpathSupport = contextNode.getXPathSupport();
191             }
192             else if (size() >0) {
193                 xpathSupport = ((NodeModel) get(0)).getXPathSupport();
194             }
195         }
196         return xpathSupport;
197     }
198 }
Popular Tags