View Javadoc

1   /*
2    * $Id: AbstractAdapterNode.java 471756 2006-11-06 15:01:43Z husted $
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         log.debug("childAdapters = " + adapters);
135         log.debug("child = " + child);
136         int index = adapters.indexOf(child);
137         if (index < 0)
138             throw new StrutsException(child + " is no child of " + this);
139         int siblingIndex = before ? index - 1 : index + 1;
140         return ((0 < siblingIndex) && (siblingIndex < adapters.size())) ?
141                 ((Node) adapters.get(siblingIndex)) : null;
142     }
143 
144     public Node getChildAfter(Node child) {
145         log.trace("getChildafter");
146         return getChildBeforeOrAfter(child, false/*after*/);
147     }
148 
149     public Node getChildBefore(Node child) {
150         log.trace("getchildbefore");
151         return getChildBeforeOrAfter(child, true/*after*/);
152     }
153 
154     public NodeList getElementsByTagName(String tagName) {
155         if (tagName.equals("*")) {
156             return getChildNodes();
157         } else {
158             LinkedList<Node> filteredChildren = new LinkedList<Node>();
159 
160             for (Node adapterNode : getChildAdapters()) {
161                 if (adapterNode.getNodeName().equals(tagName)) {
162                     filteredChildren.add(adapterNode);
163                 }
164             }
165 
166             return new SimpleNodeList(filteredChildren);
167         }
168     }
169 
170     public NodeList getElementsByTagNameNS(String string, String string1) {
171         // TODO:
172         return null;
173     }
174 
175     // Begin Node methods
176 
177     public NamedNodeMap getAttributes() {
178         return EMPTY_NAMEDNODEMAP;
179     }
180 
181     public NodeList getChildNodes() {
182         NodeList nl = new SimpleNodeList(getChildAdapters());
183         if (log.isDebugEnabled())
184             log.debug("getChildNodes for tag: "
185                     + getNodeName() + " num children: " + nl.getLength());
186         return nl;
187     }
188 
189     public Node getFirstChild() {
190         return (getChildNodes().getLength() > 0) ? getChildNodes().item(0) : null;
191     }
192 
193     public Node getLastChild() {
194         return (getChildNodes().getLength() > 0) ? getChildNodes().item(getChildNodes().getLength() - 1) : null;
195     }
196 
197 
198     public String getLocalName() {
199         return null;
200     }
201 
202     public String getNamespaceURI() {
203         return null;
204     }
205 
206     public void setNodeValue(String string) throws DOMException {
207         throw operationNotSupported();
208     }
209 
210     public String getNodeValue() throws DOMException {
211         throw operationNotSupported();
212     }
213 
214     public Document getOwnerDocument() {
215         return null;
216     }
217 
218     public Node getParentNode() {
219         log.trace("getParentNode");
220         return getParent();
221     }
222 
223     public AdapterNode getParent() {
224         return parent;
225     }
226 
227     public void setParent(AdapterNode parent) {
228         this.parent = parent;
229     }
230 
231     public Object getPropertyValue() {
232         return propertyValue;
233     }
234 
235     public void setPropertyValue(Object prop) {
236         this.propertyValue = prop;
237     }
238 
239     public void setPrefix(String string) throws DOMException {
240         throw operationNotSupported();
241     }
242 
243     public String getPrefix() {
244         return null;
245     }
246 
247     public Node getNextSibling() {
248         Node next = getParent().getChildAfter(this);
249         if (log.isTraceEnabled()) {
250             log.trace("getNextSibling on " + getNodeName() + ": "
251                     + ((next == null) ? "null" : next.getNodeName()));
252         }
253 
254         return getParent().getChildAfter(this);
255     }
256 
257     public Node getPreviousSibling() {
258         return getParent().getChildBefore(this);
259     }
260 
261     public String getPropertyName() {
262         return propertyName;
263     }
264 
265     public void setPropertyName(String name) {
266         this.propertyName = name;
267     }
268 
269     public AdapterFactory getAdapterFactory() {
270         return adapterFactory;
271     }
272 
273     public void setAdapterFactory(AdapterFactory adapterFactory) {
274         this.adapterFactory = adapterFactory;
275     }
276 
277     public boolean isSupported(String string, String string1) {
278         throw operationNotSupported();
279     }
280 
281     public Node appendChild(Node node) throws DOMException {
282         throw operationNotSupported();
283     }
284 
285     public Node cloneNode(boolean b) {
286         log.trace("cloneNode");
287         throw operationNotSupported();
288     }
289 
290     public boolean hasAttributes() {
291         return false;
292     }
293 
294     public boolean hasChildNodes() {
295         return false;
296     }
297 
298     public Node insertBefore(Node node, Node node1) throws DOMException {
299         throw operationNotSupported();
300     }
301 
302     public void normalize() {
303         log.trace("normalize");
304         throw operationNotSupported();
305     }
306 
307     public Node removeChild(Node node) throws DOMException {
308         throw operationNotSupported();
309     }
310 
311     public Node replaceChild(Node node, Node node1) throws DOMException {
312         throw operationNotSupported();
313     }
314 
315     // Begin DOM 3 methods
316 
317     public boolean isDefaultNamespace(String string) {
318         throw operationNotSupported();
319     }
320 
321     public String lookupNamespaceURI(String string) {
322         throw operationNotSupported();
323     }
324 
325     public String getNodeName() {
326         throw operationNotSupported();
327     }
328 
329     public short getNodeType() {
330         throw operationNotSupported();
331     }
332 
333     public String getBaseURI() {
334         throw operationNotSupported();
335     }
336 
337     public short compareDocumentPosition(Node node) throws DOMException {
338         throw operationNotSupported();
339     }
340 
341     public String getTextContent() throws DOMException {
342         throw operationNotSupported();
343     }
344 
345     public void setTextContent(String string) throws DOMException {
346         throw operationNotSupported();
347 
348     }
349 
350     public boolean isSameNode(Node node) {
351         throw operationNotSupported();
352     }
353 
354     public String lookupPrefix(String string) {
355         throw operationNotSupported();
356     }
357 
358     public boolean isEqualNode(Node node) {
359         throw operationNotSupported();
360     }
361 
362     public Object getFeature(String string, String string1) {
363         throw operationNotSupported();
364     }
365 
366     public Object setUserData(String string, Object object, UserDataHandler userDataHandler) {
367         throw operationNotSupported();
368     }
369 
370     public Object getUserData(String string) {
371         throw operationNotSupported();
372     }
373 
374     // End node methods
375 
376     protected StrutsException operationNotSupported() {
377         return new StrutsException("Operation not supported.");
378     }
379 
380     public String toString() {
381         return getClass() + ": " + getNodeName() + " parent=" + getParentNode();
382     }
383 }