View Javadoc

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