public static Bar bar(Foo foo, int index) {
return foo.getBar((Language)mappings.get(index));
}The idea is to have an ordering on Bar objects when evaluating xpath expressions. In the application imposing any order on Bar objects would not make sense because
a) the order can change b) conceptually there is no notion of ordering
I registered the function with:
JXPathContext context = ...; // MyFunctions contains the static method from above context.setFunctions(new ClassFunctions(MyFunctions.class, "test"));
I can then use an xpath expression like:
/test:bar(/, 1)
to extract the first bar. Of course I have to set the mapping to be used by the bar method...
By the way, I tried the empty string as namespace parameter to ClassFunctions constructor but that did not work (NullPointerException...). Is this a bug?
An even simpler version uses an ExpressionContext (as highlighted in the users guide) as follows:
public static Bar bar(ExpressionContext context, int index) {
Foo foo = (Foo)context.getContextNodePointer().getValue();
return foo.getBar((Language)mappings.get(index));
}the corresponding xpath is then:
/test:bar(1)
But I'd prefer the following (simpler) form:
/bar[1]
So I'll have to dig a bit deeper. Any help is still appreciated...
Simon
Dmitri Plotnikov wrote:
Simon,
A possible alternative to using custom NodePointers in this situation could be a custom Function.
Step 1. You implement a static method that does pretty much what you have in your example:
public class MyFunc { public static Bar barByLang(Foo foo, String ln) { Language lang = (Language)mapping.get(ln); return foo.getBar(lang); } }
Step 2. Register the MyFunc class with JXPathContext.
Step 3. Use the function like this context.getValue("barByLang(/foo, 'fr')");
Also see http://jakarta.apache.org/commons/jxpath/users-guide.html#Extension%20Functions
Now, if you insist on custom implementation of NodePointer, choose the right superclass. For example, BeanPropertyPointer might be the right one.
I hope this helps
- Dmitri
----- Original Message ----- From: "Simon Raess" <[EMAIL PROTECTED]>
To: "Jakarta Commons Users List" <[EMAIL PROTECTED]>
Sent: Thursday, June 17, 2004 5:32 PM
Subject: [jxpath] Custom NodePointer implementation
hi
I hope to get some ideas how to implement the following:
Let's say I have a class Foo that can contain several Bar instances. The Bar instances are accessed by a key, let's say a Language object. So I have the following methods in Foo:
public Bar getBar(Language l); public Set getLanguages();
In the model of my application I don't want to have an absolute ordering of Bar objects, that is I don't want to expose a method like
public Bar getBar(int index);
or similar. My idea is to have an external object impose an ordering on the Bar objects (that is an ordering on languages). The point is, that the ordering may change at runtime. What that basically means is, that I'll have a mapping from a int key to a Language. For example the mapping would contain:
Language int key de 0 fr 1 en 2
So my idea is to create a custom NodePointer that receives such a mapping definition (so it knows about the ordering of languages). The following xpath expression (with the above mapping definition) should return the text with language fr:
foo/bar[2]
This should be translated (by the custom NodePointer) to a call to:
int index = ...; Foo foo = ...; List mapping = ...; Language lang = (Language)mapping.get(index); Bar fr_bar = foo.getBar(lang);
The following xpath
foo/bar
should probably be converted to something like
List list = foo.getBar();
I'm still unconfident about the jxpath internals, so could please somebody give me some pointers how I could achieve that? I'm I on the right tracks? Which methods from NodePointer class must I override (except the abstract ones, of course)? Is there a simple example that shows how to implement a NodePointer for objects without using any reflection, introspection, ...? Is there anything else I should consider? Please ask me if I missed some important information!
best regards Simon
--------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]
--------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]
--------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]
