commons-user mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Matt Benson <gudnabr...@gmail.com>
Subject Re: [jxpath] Passing casting information within a path-based setter?
Date Sat, 30 Jul 2011 00:54:30 GMT
Quick potential suggestions:

- Set some property on the parent, and query it in your factory
- Subclass TheObject and override the dataArray accessors to TheChild[]
- Use a different factory instance that does what you want

Matt

On Fri, Jul 29, 2011 at 6:17 PM, Hippo Man <hippo.mailbox@gmail.com> wrote:
> I'm fairly new to JXPath and I have a question for which I was unable to find
> an answer in any of the places I searched for on line. I ask you in advance to
> please forgive me if the answer to my question can be found in some
> easy-to-locate
> place that I happened to overlook.
>
> Is there a way to do casting within a path-based JXPath setter? I'd like to be
> able to optionally specify that the setting of an item gets done via a
> subclass that
> has more attributes than the parent, but I couldn't find out how to do this.
>
> I'm sure that my question is not completely clear, so as you read this
> discussion, please look at the Java fragments at the bottom of this message
> to see an illustration of what I'm trying to do.
>
> Consider the sample class (below) called TheObject. It has two attributes:
> a String called "name", and an array of TheData objects.
>
> The TheData class (below) contains a single String attribute called "item".
>
> There is a subclass of TheData called TheChild, and it contains a String
> attribute called "varString", a Long attribute called "varLong", and a Double
> attribute called "varDouble".
>
> I want to use JXPath path-based setters to set the attributes within TheObject.
> I have implemented an extension of AbstractFactory called ObjectFactory
> to aid in this procedure. ObjectFactory also appears below.
>
> In the "main" method of TheObject, I instantiate my JXPath context and attach
> my ObjectFactory, after which I set some attributes. As you can see in my
> example, this works fine as long as I want my "dataArray" to be instantiated
> as an array of TheData objects and then set the "item" attribute of one of
> these instances.
>
> But sometimes, I might want to instantiate "dataArray" with an array of TheChild
> objects. I would like this instantiation to take place within
> "createObject", and I'd
> like it to be able to determine at runtime via some sort of syntax in
> the path setter
> that "createObject" should instantiate with TheChild objects instead of TheData
> objects.
>
> In other words, is there some sort of "casting" syntax that I can pass into the
> path setter which I can then see within the "name" or "pointer" parameters to
> "createObject" which can tell me that I have to instantiate that array with
> TheChild objects instead of TheData objects?
>
> For the purpose of illustration, I gave an unworkable example of casting
> syntax within the "main" method of TheObject, below. That example shows
> exactly what I'm trying to do.
>
> Thanks in advance for any pointers to documentation or any other help that
> any of you might be able to give me.
>
> Here are the Java code fragments that I mentioned above ...
>
> public class TheObject {
>    protected String      name      = null;
>    protected TheData[]   dataArray = null;
>    // constructor, getters, setters, and toString have been left out
>
>    public static void main(String[] argv) {
>        TheObject obj = new TheObject();
>        JXPathContext context = JXPathContext.newContext(obj);
>        context.setFactory(new ObjectFactory());
>
>        context.createPathAndSetValue("/name", "foo"); // this works
>        context.createPathAndSetValue("/dataArray[1]/item", "bar");
> // this works
>
>        // But instead of setting "item" as I did above, is there something
>        // I can do syntactically in the path that I can see within the "name"
>        // or "pointer" arguments that are passed to the createObject() method
>        // of ObjectFactory, which would specify that "dataArray" should be
>        // instantiated as an array of TheChild objects instead of as an array
>        // of TheData objects?  Something analogous to this (I know this doesn't
>        // work; it's just for illustration) ...
>
>        context.createPathAndSetValue("/{cast to
> TheChild}dataArray[1]/varString", "quack");
>
>        System.out.println(obj);
>
>        System.exit(0);
>    }
> }
>
> public class TheData {
>    protected String item = null;
>    // constructor, getters, setters, and toString have been left out
> }
>
> public class TheChild extends TheData {
>    protected String varString = null;
>    protected Long   varLong   = null;
>    protected Double varDouble = null;
>    // constructor, getters, setters, and toString have been left out
> }
>
> public class ObjectFactory extends AbstractFactory {
>
>    @Override
>    public boolean createObject(JXPathContext context, Pointer
> pointer, Object parent, String name, int index) {
>        System.out.println("createObject: pointer: " + pointer + ",
> parent: " + parent.getClass().getName() + ", name: " + name + ",
> index: " + index);
>
>        if (parent instanceof TheObject) {
>
>            // Is there something I can pass in via the path setter or that
>            // I can access via "pointer" which will tell me that I
> want to instantiate
>            // the data array with instances of TheChild instead of TheData?
>
>            if (name.equalsIgnoreCase("dataArray")) {
>                TheData[] data = new TheData[index + 1];
>                TheData[] oldData = ((TheObject) parent).getDataArray();
>                int nold = (oldData == null ? 0 : oldData.length);
>                for (int n = 0; n <= index; n++) {
>                    if (n < nold) {
>                        data[n] = oldData[n];
>                    }
>                    else {
>                        data[n] = new TheData();
>                    }
>                }
>                for (int n = index + 1; n < nold; n++) {
>                    data[n] = oldData[n];
>                }
>                ((TheObject) parent).setDataArray(data);
>            }
>            return (true);
>        }
>        return (false);
>    }
> }
>
> --
>  hippo.mailbox@gmail.com
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: user-unsubscribe@commons.apache.org
> For additional commands, e-mail: user-help@commons.apache.org
>
>

---------------------------------------------------------------------
To unsubscribe, e-mail: user-unsubscribe@commons.apache.org
For additional commands, e-mail: user-help@commons.apache.org


Mime
View raw message