1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46 package org.jaxen.javabean;
47
48 import java.lang.reflect.Method;
49 import java.lang.reflect.InvocationTargetException;
50 import java.util.Iterator;
51 import java.util.Collection;
52
53 import org.jaxen.DefaultNavigator;
54 import org.jaxen.FunctionCallException;
55 import org.jaxen.NamedAccessNavigator;
56 import org.jaxen.Navigator;
57 import org.jaxen.XPath;
58 import org.jaxen.JaxenConstants;
59 import org.jaxen.util.SingleObjectIterator;
60
61 /***
62 * Interface for navigating around a JavaBean object model.
63 *
64 * <p>
65 * This class is not intended for direct usage, but is
66 * used by the Jaxen engine during evaluation.
67 * </p>
68 *
69 * @see XPath
70 *
71 * @author <a href="mailto:bob@werken.com">bob mcwhirter</a>
72 */
73 public class DocumentNavigator
74 extends DefaultNavigator
75 implements NamedAccessNavigator
76 {
77
78 /*** Empty Class array. */
79 private static final Class[] EMPTY_CLASS_ARRAY = new Class[0];
80
81 /*** Empty Object array. */
82 private static final Object[] EMPTY_OBJECT_ARRAY = new Object[0];
83
84 /*** Singleton implementation.
85 */
86 private static final DocumentNavigator instance = new DocumentNavigator();
87
88 /*** Retrieve the singleton instance of this <code>DocumentNavigator</code>.
89 */
90 public static Navigator getInstance()
91 {
92 return instance;
93 }
94
95 public boolean isElement(Object obj)
96 {
97 return (obj instanceof Element);
98 }
99
100 public boolean isComment(Object obj)
101 {
102 return false;
103 }
104
105 public boolean isText(Object obj)
106 {
107 return ( obj instanceof String );
108 }
109
110 public boolean isAttribute(Object obj)
111 {
112 return false;
113 }
114
115 public boolean isProcessingInstruction(Object obj)
116 {
117 return false;
118 }
119
120 public boolean isDocument(Object obj)
121 {
122 return false;
123 }
124
125 public boolean isNamespace(Object obj)
126 {
127 return false;
128 }
129
130 public String getElementName(Object obj)
131 {
132 return ((Element)obj).getName();
133 }
134
135 public String getElementNamespaceUri(Object obj)
136 {
137 return "";
138 }
139
140 public String getElementQName(Object obj)
141 {
142 return "";
143 }
144
145 public String getAttributeName(Object obj)
146 {
147 return "";
148 }
149
150 public String getAttributeNamespaceUri(Object obj)
151 {
152 return "";
153 }
154
155 public String getAttributeQName(Object obj)
156 {
157 return "";
158 }
159
160 public Iterator getChildAxisIterator(Object contextNode)
161 {
162 return JaxenConstants.EMPTY_ITERATOR;
163 }
164
165 /***
166 * Retrieves an <code>Iterator</code> over the child elements that
167 * match the supplied name.
168 *
169 * @param contextNode the origin context node
170 * @param localName the local name of the children to return, always present
171 * @param namespacePrefix the prefix of the namespace of the children to return
172 * @param namespaceURI the namespace URI of the children to return
173 * @return an Iterator that traverses the named children, or null if none
174 */
175 public Iterator getChildAxisIterator(Object contextNode,
176 String localName,
177 String namespacePrefix,
178 String namespaceURI)
179 {
180 Class cls = ((Element)contextNode).getObject().getClass();
181
182 String methodName = javacase( localName );
183
184 Method method = null;
185
186 try
187 {
188 method = cls.getMethod( "get" + methodName, EMPTY_CLASS_ARRAY );
189 }
190 catch (NoSuchMethodException e)
191 {
192 try
193 {
194 method = cls.getMethod( "get" + methodName + "s", EMPTY_CLASS_ARRAY );
195 }
196 catch (NoSuchMethodException ee)
197 {
198 try
199 {
200 method = cls.getMethod( localName, EMPTY_CLASS_ARRAY );
201 }
202 catch (NoSuchMethodException eee)
203 {
204 method = null;
205 }
206 }
207 }
208
209 if ( method == null )
210 {
211 return JaxenConstants.EMPTY_ITERATOR;
212 }
213
214 try
215 {
216 Object result = method.invoke( ((Element)contextNode).getObject(), EMPTY_OBJECT_ARRAY );
217
218 if ( result == null )
219 {
220 return JaxenConstants.EMPTY_ITERATOR;
221 }
222
223 if ( result instanceof Collection )
224 {
225 return new ElementIterator( (Element) contextNode, localName, ((Collection)result).iterator() );
226 }
227
228 if ( result.getClass().isArray() )
229 {
230 return JaxenConstants.EMPTY_ITERATOR;
231 }
232
233 return new SingleObjectIterator( new Element( (Element) contextNode, localName, result ) );
234 }
235 catch (IllegalAccessException e)
236 {
237
238 }
239 catch (InvocationTargetException e)
240 {
241
242 }
243
244 return JaxenConstants.EMPTY_ITERATOR;
245 }
246
247 public Iterator getParentAxisIterator(Object contextNode)
248 {
249 if ( contextNode instanceof Element )
250 {
251 return new SingleObjectIterator( ((Element)contextNode).getParent() );
252 }
253
254 return JaxenConstants.EMPTY_ITERATOR;
255 }
256
257 public Iterator getAttributeAxisIterator(Object contextNode)
258 {
259 return JaxenConstants.EMPTY_ITERATOR;
260 }
261
262 /***
263 * Retrieves an <code>Iterator</code> over the attribute elements that
264 * match the supplied name.
265 *
266 * @param contextNode the origin context node
267 * @param localName the local name of the attributes to return, always present
268 * @param namespacePrefix the prefix of the namespace of the attributes to return
269 * @param namespaceURI the namespace URI of the attributes to return
270 * @return an Iterator that traverses the named attributes, not null
271 */
272 public Iterator getAttributeAxisIterator(Object contextNode,
273 String localName,
274 String namespacePrefix,
275 String namespaceURI) {
276 return JaxenConstants.EMPTY_ITERATOR;
277 }
278
279 public Iterator getNamespaceAxisIterator(Object contextNode)
280 {
281 return JaxenConstants.EMPTY_ITERATOR;
282 }
283
284 public Object getDocumentNode(Object contextNode)
285 {
286 return null;
287 }
288
289 public Object getParentNode(Object contextNode)
290 {
291 if ( contextNode instanceof Element )
292 {
293 return ((Element)contextNode).getParent();
294 }
295
296 return JaxenConstants.EMPTY_ITERATOR;
297 }
298
299 public String getTextStringValue(Object obj)
300 {
301 if ( obj instanceof Element )
302 {
303 return ((Element)obj).getObject().toString();
304 }
305 return obj.toString();
306 }
307
308 public String getElementStringValue(Object obj)
309 {
310 if ( obj instanceof Element )
311 {
312 return ((Element)obj).getObject().toString();
313 }
314 return obj.toString();
315 }
316
317 public String getAttributeStringValue(Object obj)
318 {
319 return obj.toString();
320 }
321
322 public String getNamespaceStringValue(Object obj)
323 {
324 return obj.toString();
325 }
326
327 public String getNamespacePrefix(Object obj)
328 {
329 return null;
330 }
331
332 public String getCommentStringValue(Object obj)
333 {
334 return null;
335 }
336
337 public String translateNamespacePrefixToUri(String prefix, Object context)
338 {
339 return null;
340 }
341
342 public short getNodeType(Object node)
343 {
344 return 0;
345 }
346
347 public Object getDocument(String uri) throws FunctionCallException
348 {
349 return null;
350 }
351
352 public String getProcessingInstructionTarget(Object obj)
353 {
354 return null;
355 }
356
357 public String getProcessingInstructionData(Object obj)
358 {
359 return null;
360 }
361
362 public XPath parseXPath(String xpath)
363 throws org.jaxen.saxpath.SAXPathException
364 {
365 return new JavaBeanXPath( xpath );
366 }
367
368 protected String javacase(String name)
369 {
370 if ( name.length() == 0 )
371 {
372 return name;
373 }
374 else if ( name.length() == 1 )
375 {
376 return name.toUpperCase();
377 }
378
379 return name.substring( 0, 1 ).toUpperCase() + name.substring( 1 );
380 }
381 }