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 class Singleton
87 {
88 /*** Singleton instance.
89 */
90 private static DocumentNavigator instance = new DocumentNavigator();
91 }
92
93 /*** Retrieve the singleton instance of this <code>DocumentNavigator</code>.
94 */
95 public static Navigator getInstance()
96 {
97 return Singleton.instance;
98 }
99
100 public boolean isElement(Object obj)
101 {
102 return (obj instanceof Element);
103 }
104
105 public boolean isComment(Object obj)
106 {
107 return false;
108 }
109
110 public boolean isText(Object obj)
111 {
112 return ( obj instanceof String );
113 }
114
115 public boolean isAttribute(Object obj)
116 {
117 return false;
118 }
119
120 public boolean isProcessingInstruction(Object obj)
121 {
122 return false;
123 }
124
125 public boolean isDocument(Object obj)
126 {
127 return false;
128 }
129
130 public boolean isNamespace(Object obj)
131 {
132 return false;
133 }
134
135 public String getElementName(Object obj)
136 {
137 return ((Element)obj).getName();
138 }
139
140 public String getElementNamespaceUri(Object obj)
141 {
142 return "";
143 }
144
145 public String getElementQName(Object obj)
146 {
147 return "";
148 }
149
150 public String getAttributeName(Object obj)
151 {
152 return "";
153 }
154
155 public String getAttributeNamespaceUri(Object obj)
156 {
157 return "";
158 }
159
160 public String getAttributeQName(Object obj)
161 {
162 return "";
163 }
164
165 public Iterator getChildAxisIterator(Object contextNode)
166 {
167 return JaxenConstants.EMPTY_ITERATOR;
168 }
169
170 /***
171 * Retrieves an <code>Iterator</code> over the child elements that
172 * match the supplied name.
173 *
174 * @param contextNode the origin context node
175 * @param localName the local name of the children to return, always present
176 * @param namespacePrefix the prefix of the namespace of the children to return
177 * @param namespaceURI the uri of the namespace of the children to return
178 * @return an Iterator that traverses the named children, or null if none
179 */
180 public Iterator getChildAxisIterator(Object contextNode,
181 String localName,
182 String namespacePrefix,
183 String namespaceURI)
184 {
185 Class cls = ((Element)contextNode).getObject().getClass();
186
187 String methodName = javacase( localName );
188
189 Method method = null;
190
191 try
192 {
193 method = cls.getMethod( "get" + methodName, EMPTY_CLASS_ARRAY );
194 }
195 catch (NoSuchMethodException e)
196 {
197 try
198 {
199 method = cls.getMethod( "get" + methodName + "s", EMPTY_CLASS_ARRAY );
200 }
201 catch (NoSuchMethodException ee)
202 {
203 try
204 {
205 method = cls.getMethod( localName, EMPTY_CLASS_ARRAY );
206 }
207 catch (NoSuchMethodException eee)
208 {
209 method = null;
210 }
211 }
212 }
213
214 if ( method == null )
215 {
216 return JaxenConstants.EMPTY_ITERATOR;
217 }
218
219 try
220 {
221 Object result = method.invoke( ((Element)contextNode).getObject(), EMPTY_OBJECT_ARRAY );
222
223 if ( result == null )
224 {
225 return JaxenConstants.EMPTY_ITERATOR;
226 }
227
228 if ( result instanceof Collection )
229 {
230 return new ElementIterator( (Element) contextNode, localName, ((Collection)result).iterator() );
231 }
232
233 if ( result.getClass().isArray() )
234 {
235 return JaxenConstants.EMPTY_ITERATOR;
236 }
237
238 return new SingleObjectIterator( new Element( (Element) contextNode, localName, result ) );
239 }
240 catch (IllegalAccessException e)
241 {
242
243 }
244 catch (InvocationTargetException e)
245 {
246
247 }
248
249 return JaxenConstants.EMPTY_ITERATOR;
250 }
251
252 public Iterator getParentAxisIterator(Object contextNode)
253 {
254 if ( contextNode instanceof Element )
255 {
256 return new SingleObjectIterator( ((Element)contextNode).getParent() );
257 }
258
259 return JaxenConstants.EMPTY_ITERATOR;
260 }
261
262 public Iterator getAttributeAxisIterator(Object contextNode)
263 {
264 return JaxenConstants.EMPTY_ITERATOR;
265 }
266
267 /***
268 * Retrieves an <code>Iterator</code> over the attribute elements that
269 * match the supplied name.
270 *
271 * @param contextNode the origin context node
272 * @param localName the local name of the attributes to return, always present
273 * @param namespacePrefix the prefix of the namespace of the attributes to return
274 * @param namespaceURI the uri of the namespace of the attributes to return
275 * @return an Iterator that traverses the named attributes, not null
276 */
277 public Iterator getAttributeAxisIterator(Object contextNode,
278 String localName,
279 String namespacePrefix,
280 String namespaceURI) {
281 return JaxenConstants.EMPTY_ITERATOR;
282 }
283
284 public Iterator getNamespaceAxisIterator(Object contextNode)
285 {
286 return JaxenConstants.EMPTY_ITERATOR;
287 }
288
289 public Object getDocumentNode(Object contextNode)
290 {
291 return null;
292 }
293
294 public Object getParentNode(Object contextNode)
295 {
296 if ( contextNode instanceof Element )
297 {
298 return ((Element)contextNode).getParent();
299 }
300
301 return JaxenConstants.EMPTY_ITERATOR;
302 }
303
304 public String getTextStringValue(Object obj)
305 {
306 if ( obj instanceof Element )
307 {
308 return ((Element)obj).getObject().toString();
309 }
310 return obj.toString();
311 }
312
313 public String getElementStringValue(Object obj)
314 {
315 if ( obj instanceof Element )
316 {
317 return ((Element)obj).getObject().toString();
318 }
319 return obj.toString();
320 }
321
322 public String getAttributeStringValue(Object obj)
323 {
324 return obj.toString();
325 }
326
327 public String getNamespaceStringValue(Object obj)
328 {
329 return obj.toString();
330 }
331
332 public String getNamespacePrefix(Object obj)
333 {
334 return null;
335 }
336
337 public String getCommentStringValue(Object obj)
338 {
339 return null;
340 }
341
342 public String translateNamespacePrefixToUri(String prefix, Object context)
343 {
344 return null;
345 }
346
347 public short getNodeType(Object node)
348 {
349 return 0;
350 }
351
352 public Object getDocument(String uri) throws FunctionCallException
353 {
354 return null;
355 }
356
357 public String getProcessingInstructionTarget(Object obj)
358 {
359 return null;
360 }
361
362 public String getProcessingInstructionData(Object obj)
363 {
364 return null;
365 }
366
367 public XPath parseXPath(String xpath)
368 throws org.jaxen.saxpath.SAXPathException
369 {
370 return new JavaBeanXPath( xpath );
371 }
372
373 protected String javacase(String name)
374 {
375 if ( name.length() == 0 )
376 {
377 return name;
378 }
379 else if ( name.length() == 1 )
380 {
381 return name.toUpperCase();
382 }
383
384 return name.substring( 0, 1 ).toUpperCase() + name.substring( 1 );
385 }
386 }