1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
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
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
151 }
152
153 public Node getChildBefore(Node child) {
154 log.trace("getchildbefore");
155 return getChildBeforeOrAfter(child, true
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
176 return null;
177 }
178
179
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
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
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 }