View Javadoc

1   /*
2    * $Id: AbstractAdapterNode.java 575840 2007-09-15 01:05:16Z jholmes $
3    *
4    * Licensed to the Apache Software Foundation (ASF) under one
5    * or more contributor license agreements.  See the NOTICE file
6    * distributed with this work for additional information
7    * regarding copyright ownership.  The ASF licenses this file
8    * to you under the Apache License, Version 2.0 (the
9    * "License"); you may not use this file except in compliance
10   * with the License.  You may obtain a copy of the License at
11   *
12   *  http://www.apache.org/licenses/LICENSE-2.0
13   *
14   * Unless required by applicable law or agreed to in writing,
15   * software distributed under the License is distributed on an
16   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17   * KIND, either express or implied.  See the License for the
18   * specific language governing permissions and limitations
19   * under the License.
20   */
21  package org.apache.struts2.views.xslt;
22  
23  import java.util.ArrayList;
24  import java.util.LinkedList;
25  import java.util.List;
26  
27  import org.apache.commons.logging.Log;
28  import org.apache.commons.logging.LogFactory;
29  import org.apache.struts2.StrutsException;
30  import org.w3c.dom.DOMException;
31  import org.w3c.dom.Document;
32  import org.w3c.dom.NamedNodeMap;
33  import org.w3c.dom.Node;
34  import org.w3c.dom.NodeList;
35  import org.w3c.dom.UserDataHandler;
36  
37  /***
38   * AbstractAdapterNode is the base for childAdapters that expose a read-only view
39   * of a Java object as a DOM Node.  This class implements the core parent-child
40   * and sibling node traversal functionality shared by all adapter type nodes
41   * and used in proxy node support.
42   *
43   * @see AbstractAdapterElement
44   */
45  public abstract class AbstractAdapterNode implements AdapterNode {
46  
47      private static final NamedNodeMap EMPTY_NAMEDNODEMAP =
48              new NamedNodeMap() {
49                  public int getLength() {
50                      return 0;
51                  }
52  
53                  public Node item(int index) {
54                      return null;
55                  }
56  
57                  public Node getNamedItem(String name) {
58                      return null;
59                  }
60  
61                  public Node removeNamedItem(String name) throws DOMException {
62                      return null;
63                  }
64  
65                  public Node setNamedItem(Node arg) throws DOMException {
66                      return null;
67                  }
68  
69                  public Node setNamedItemNS(Node arg) throws DOMException {
70                      return null;
71                  }
72  
73                  public Node getNamedItemNS(String namespaceURI, String localName) {
74                      return null;
75                  }
76  
77                  public Node removeNamedItemNS(String namespaceURI, String localName) throws DOMException {
78                      return null;
79                  }
80              };
81  
82      private List<Node> childAdapters;
83      private Log log = LogFactory.getLog(this.getClass());
84  
85      // The domain object that we are adapting
86      private Object propertyValue;
87      private String propertyName;
88      private AdapterNode parent;
89      private AdapterFactory adapterFactory;
90  
91  
92      public AbstractAdapterNode() {
93          if (LogFactory.getLog(getClass()).isDebugEnabled()) {
94              LogFactory.getLog(getClass()).debug("Creating " + this);
95          }
96      }
97  
98      /***
99       *
100      * @param adapterFactory
101      * @param parent
102      * @param propertyName
103      * @param value
104      */
105     protected void setContext(AdapterFactory adapterFactory, AdapterNode parent, String propertyName, Object value) {
106         setAdapterFactory(adapterFactory);
107         setParent(parent);
108         setPropertyName(propertyName);
109         setPropertyValue(value);
110     }
111 
112     /***
113      * subclasses override to produce their children
114      *
115      * @return List of child adapters.
116      */
117     protected List<Node> buildChildAdapters() {
118         return new ArrayList<Node>();
119     }
120 
121     /***
122      * Lazily initialize child childAdapters
123      */
124     protected List<Node> getChildAdapters() {
125         if (childAdapters == null) {
126             childAdapters = buildChildAdapters();
127         }
128         return childAdapters;
129     }
130 
131     public Node getChildBeforeOrAfter(Node child, boolean before) {
132         log.debug("getChildBeforeOrAfter: ");
133         List adapters = getChildAdapters();
134         if (log.isDebugEnabled()) {
135             log.debug("childAdapters = " + adapters);
136             log.debug("child = " + child);
137         }
138         int index = adapters.indexOf(child);
139         if (index < 0)
140             throw new StrutsException(child + " is no child of " + this);
141         int siblingIndex = before ? index - 1 : index + 1;
142         return ((0 < siblingIndex) && (siblingIndex < adapters.size())) ?
143                 ((Node) adapters.get(siblingIndex)) : null;
144     }
145 
146     public Node getChildAfter(Node child) {
147         log.trace("getChildafter");
148         return getChildBeforeOrAfter(child, false/*after*/);
149     }
150 
151     public Node getChildBefore(Node child) {
152         log.trace("getchildbefore");
153         return getChildBeforeOrAfter(child, true/*after*/);
154     }
155 
156     public NodeList getElementsByTagName(String tagName) {
157         if (tagName.equals("*")) {
158             return getChildNodes();
159         } else {
160             LinkedList<Node> filteredChildren = new LinkedList<Node>();
161 
162             for (Node adapterNode : getChildAdapters()) {
163                 if (adapterNode.getNodeName().equals(tagName)) {
164                     filteredChildren.add(adapterNode);
165                 }
166             }
167 
168             return new SimpleNodeList(filteredChildren);
169         }
170     }
171 
172     public NodeList getElementsByTagNameNS(String string, String string1) {
173         // TODO:
174         return null;
175     }
176 
177     // Begin Node methods
178 
179     public NamedNodeMap getAttributes() {
180         return EMPTY_NAMEDNODEMAP;
181     }
182 
183     public NodeList getChildNodes() {
184         NodeList nl = new SimpleNodeList(getChildAdapters());
185         if (log.isDebugEnabled())
186             log.debug("getChildNodes for tag: "
187                     + getNodeName() + " num children: " + nl.getLength());
188         return nl;
189     }
190 
191     public Node getFirstChild() {
192         return (getChildNodes().getLength() > 0) ? getChildNodes().item(0) : null;
193     }
194 
195     public Node getLastChild() {
196         return (getChildNodes().getLength() > 0) ? getChildNodes().item(getChildNodes().getLength() - 1) : null;
197     }
198 
199 
200     public String getLocalName() {
201         return null;
202     }
203 
204     public String getNamespaceURI() {
205         return null;
206     }
207 
208     public void setNodeValue(String string) throws DOMException {
209         throw operationNotSupported();
210     }
211 
212     public String getNodeValue() throws DOMException {
213         throw operationNotSupported();
214     }
215 
216     public Document getOwnerDocument() {
217         return null;
218     }
219 
220     public Node getParentNode() {
221         log.trace("getParentNode");
222         return getParent();
223     }
224 
225     public AdapterNode getParent() {
226         return parent;
227     }
228 
229     public void setParent(AdapterNode parent) {
230         this.parent = parent;
231     }
232 
233     public Object getPropertyValue() {
234         return propertyValue;
235     }
236 
237     public void setPropertyValue(Object prop) {
238         this.propertyValue = prop;
239     }
240 
241     public void setPrefix(String string) throws DOMException {
242         throw operationNotSupported();
243     }
244 
245     public String getPrefix() {
246         return null;
247     }
248 
249     public Node getNextSibling() {
250         Node next = getParent().getChildAfter(this);
251         if (log.isTraceEnabled()) {
252             log.trace("getNextSibling on " + getNodeName() + ": "
253                     + ((next == null) ? "null" : next.getNodeName()));
254         }
255 
256         return next;
257     }
258 
259     public Node getPreviousSibling() {
260         return getParent().getChildBefore(this);
261     }
262 
263     public String getPropertyName() {
264         return propertyName;
265     }
266 
267     public void setPropertyName(String name) {
268         this.propertyName = name;
269     }
270 
271     public AdapterFactory getAdapterFactory() {
272         return adapterFactory;
273     }
274 
275     public void setAdapterFactory(AdapterFactory adapterFactory) {
276         this.adapterFactory = adapterFactory;
277     }
278 
279     public boolean isSupported(String string, String string1) {
280         throw operationNotSupported();
281     }
282 
283     public Node appendChild(Node node) throws DOMException {
284         throw operationNotSupported();
285     }
286 
287     public Node cloneNode(boolean b) {
288         log.trace("cloneNode");
289         throw operationNotSupported();
290     }
291 
292     public boolean hasAttributes() {
293         return false;
294     }
295 
296     public boolean hasChildNodes() {
297         return false;
298     }
299 
300     public Node insertBefore(Node node, Node node1) throws DOMException {
301         throw operationNotSupported();
302     }
303 
304     public void normalize() {
305         log.trace("normalize");
306         throw operationNotSupported();
307     }
308 
309     public Node removeChild(Node node) throws DOMException {
310         throw operationNotSupported();
311     }
312 
313     public Node replaceChild(Node node, Node node1) throws DOMException {
314         throw operationNotSupported();
315     }
316 
317     // Begin DOM 3 methods
318 
319     public boolean isDefaultNamespace(String string) {
320         throw operationNotSupported();
321     }
322 
323     public String lookupNamespaceURI(String string) {
324         throw operationNotSupported();
325     }
326 
327     public String getNodeName() {
328         throw operationNotSupported();
329     }
330 
331     public short getNodeType() {
332         throw operationNotSupported();
333     }
334 
335     public String getBaseURI() {
336         throw operationNotSupported();
337     }
338 
339     public short compareDocumentPosition(Node node) throws DOMException {
340         throw operationNotSupported();
341     }
342 
343     public String getTextContent() throws DOMException {
344         throw operationNotSupported();
345     }
346 
347     public void setTextContent(String string) throws DOMException {
348         throw operationNotSupported();
349 
350     }
351 
352     public boolean isSameNode(Node node) {
353         throw operationNotSupported();
354     }
355 
356     public String lookupPrefix(String string) {
357         throw operationNotSupported();
358     }
359 
360     public boolean isEqualNode(Node node) {
361         throw operationNotSupported();
362     }
363 
364     public Object getFeature(String string, String string1) {
365         throw operationNotSupported();
366     }
367 
368     public Object setUserData(String string, Object object, UserDataHandler userDataHandler) {
369         throw operationNotSupported();
370     }
371 
372     public Object getUserData(String string) {
373         throw operationNotSupported();
374     }
375 
376     // End node methods
377 
378     protected StrutsException operationNotSupported() {
379         return new StrutsException("Operation not supported.");
380     }
381 
382     public String toString() {
383         return getClass() + ": " + getNodeName() + " parent=" + getParentNode();
384     }
385 }