001: /*
002: * $Id: AbstractAdapterNode.java 575840 2007-09-15 01:05:16Z jholmes $
003: *
004: * Licensed to the Apache Software Foundation (ASF) under one
005: * or more contributor license agreements. See the NOTICE file
006: * distributed with this work for additional information
007: * regarding copyright ownership. The ASF licenses this file
008: * to you under the Apache License, Version 2.0 (the
009: * "License"); you may not use this file except in compliance
010: * with the License. You may obtain a copy of the License at
011: *
012: * http://www.apache.org/licenses/LICENSE-2.0
013: *
014: * Unless required by applicable law or agreed to in writing,
015: * software distributed under the License is distributed on an
016: * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
017: * KIND, either express or implied. See the License for the
018: * specific language governing permissions and limitations
019: * under the License.
020: */
021: package org.apache.struts2.views.xslt;
022:
023: import java.util.ArrayList;
024: import java.util.LinkedList;
025: import java.util.List;
026:
027: import org.apache.commons.logging.Log;
028: import org.apache.commons.logging.LogFactory;
029: import org.apache.struts2.StrutsException;
030: import org.w3c.dom.DOMException;
031: import org.w3c.dom.Document;
032: import org.w3c.dom.NamedNodeMap;
033: import org.w3c.dom.Node;
034: import org.w3c.dom.NodeList;
035: import org.w3c.dom.UserDataHandler;
036:
037: /**
038: * AbstractAdapterNode is the base for childAdapters that expose a read-only view
039: * of a Java object as a DOM Node. This class implements the core parent-child
040: * and sibling node traversal functionality shared by all adapter type nodes
041: * and used in proxy node support.
042: *
043: * @see AbstractAdapterElement
044: */
045: public abstract class AbstractAdapterNode implements AdapterNode {
046:
047: private static final NamedNodeMap EMPTY_NAMEDNODEMAP = new NamedNodeMap() {
048: public int getLength() {
049: return 0;
050: }
051:
052: public Node item(int index) {
053: return null;
054: }
055:
056: public Node getNamedItem(String name) {
057: return null;
058: }
059:
060: public Node removeNamedItem(String name) throws DOMException {
061: return null;
062: }
063:
064: public Node setNamedItem(Node arg) throws DOMException {
065: return null;
066: }
067:
068: public Node setNamedItemNS(Node arg) throws DOMException {
069: return null;
070: }
071:
072: public Node getNamedItemNS(String namespaceURI, String localName) {
073: return null;
074: }
075:
076: public Node removeNamedItemNS(String namespaceURI,
077: String localName) throws DOMException {
078: return null;
079: }
080: };
081:
082: private List<Node> childAdapters;
083: private Log log = LogFactory.getLog(this .getClass());
084:
085: // The domain object that we are adapting
086: private Object propertyValue;
087: private String propertyName;
088: private AdapterNode parent;
089: private AdapterFactory adapterFactory;
090:
091: public AbstractAdapterNode() {
092: if (LogFactory.getLog(getClass()).isDebugEnabled()) {
093: LogFactory.getLog(getClass()).debug("Creating " + this );
094: }
095: }
096:
097: /**
098: *
099: * @param adapterFactory
100: * @param parent
101: * @param propertyName
102: * @param value
103: */
104: protected void setContext(AdapterFactory adapterFactory,
105: 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())) ? ((Node) adapters
143: .get(siblingIndex))
144: : null;
145: }
146:
147: public Node getChildAfter(Node child) {
148: log.trace("getChildafter");
149: return getChildBeforeOrAfter(child, false/*after*/);
150: }
151:
152: public Node getChildBefore(Node child) {
153: log.trace("getchildbefore");
154: return getChildBeforeOrAfter(child, true/*after*/);
155: }
156:
157: public NodeList getElementsByTagName(String tagName) {
158: if (tagName.equals("*")) {
159: return getChildNodes();
160: } else {
161: LinkedList<Node> filteredChildren = new LinkedList<Node>();
162:
163: for (Node adapterNode : getChildAdapters()) {
164: if (adapterNode.getNodeName().equals(tagName)) {
165: filteredChildren.add(adapterNode);
166: }
167: }
168:
169: return new SimpleNodeList(filteredChildren);
170: }
171: }
172:
173: public NodeList getElementsByTagNameNS(String string, String string1) {
174: // TODO:
175: return null;
176: }
177:
178: // Begin Node methods
179:
180: public NamedNodeMap getAttributes() {
181: return EMPTY_NAMEDNODEMAP;
182: }
183:
184: public NodeList getChildNodes() {
185: NodeList nl = new SimpleNodeList(getChildAdapters());
186: if (log.isDebugEnabled())
187: log.debug("getChildNodes for tag: " + getNodeName()
188: + " num children: " + nl.getLength());
189: return nl;
190: }
191:
192: public Node getFirstChild() {
193: return (getChildNodes().getLength() > 0) ? getChildNodes()
194: .item(0) : null;
195: }
196:
197: public Node getLastChild() {
198: return (getChildNodes().getLength() > 0) ? getChildNodes()
199: .item(getChildNodes().getLength() - 1) : null;
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,
371: UserDataHandler userDataHandler) {
372: throw operationNotSupported();
373: }
374:
375: public Object getUserData(String string) {
376: throw operationNotSupported();
377: }
378:
379: // End node methods
380:
381: protected StrutsException operationNotSupported() {
382: return new StrutsException("Operation not supported.");
383: }
384:
385: public String toString() {
386: return getClass() + ": " + getNodeName() + " parent="
387: + getParentNode();
388: }
389: }
|