View Javadoc

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