You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@commons.apache.org by Adam J Chesney <ad...@multicom.co.uk> on 2003/02/04 14:41:56 UTC

[JXPath] creating sequences

Hi,

I am new to JXPath but it looks great, thanks for all your hard work. I have just been playing around with it a little as I would like to use it in a new project that I am working on. I wanted to implement a generic Factory to create objects and I ran into a small snag. I just wanted to run this by you. My GenericFactory (attached) is a bit rough around the edges but it automatically creates properties using reflection to find the appropriate set method on the parent object, and then instantiates an instance of the appropriate class (parameter type). This works fine for straight beans but using the same method for sequences causes a problem because atm it is not possible to determine whether or not the target property is a sequence or not. If you can determine that you are creating a sequence then it is possible (in some circumstances) to determine the type of the objects to be added to the newly created sequence, and to add them during the construction of the sequence property. This won't work for generic Collections, but it will work for custom sequences that implement List, which is what I am using (Castor based beans). 

By changing line 178 in 

org.apache.commons.jxpath.ri.model.beans.PropertyPointer.java

from

     int inx = (index == WHOLE_COLLECTION ? 0 : index);

to

     int inx = (index == WHOLE_COLLECTION ? -1 : index);

I am now able to determine whether or not the target property for construction is a sequence and is accessed using an index and I can therefore, in the factory, create the required number of objects. Previously, it was impossible to tell the difference between /myList and /myList[1] because the index passed to the Factory in both cases is 0.

So I can now execute calls like:

context.createPathAndSetValue("/myList[2]/name", "harry");

Even though myList is null to start with, the GenericFactory can determine that myList is a sequence and it can create 2 objects to add into it after creating and sequence and assigning it to the root context.

Anyway, I don't think this change should negatively effect anyone and so I thought that maybe you could add it to the main tree. If it's not possible, then no problem, I can maintain my own version. I guess a change like this could potentially cause problems if the Factory coding was a bit "lazy".

Anyway, once agin, thanks for this kewl tool.

Warm regards,

Adam Chesney.


=====================================================
 
Tel:   (+44) 117 908 1254 (Direct)
Mobile (+44) 7780 962 961
email: adam@multicom.co.uk
 
This communication is intended solely for the addressee and is confidential.
If you are not the intended recipient, any disclosure, copying, distribution
or any action taken or omitted to be taken in reliance on it, is prohibited
and may be unlawful.
 
Although this e-mail and any attachments are believed to be free of any
virus, or any other defect which might affect any computer or IT system into
which they are received and opened, it is the responsibility of the
recipient to ensure that they are virus free and no responsibility is
accepted by Multicom Products Limited for any loss or damage arising in any
way from receipt or use thereof.

Re: [JXPath] creating sequences

Posted by Adam J Chesney <ad...@multicom.co.uk>.
Oh, okay I understand now. The factory may get called even when the target
is not null. That explains my confusion.

Thanks again.

Adam.


----- Original Message -----
From: "Dmitri Plotnikov" <dp...@yahoo.com>
To: "Jakarta Commons Developers List" <co...@jakarta.apache.org>
Sent: Tuesday, February 04, 2003 6:25 PM
Subject: Re: [JXPath] creating sequences


> Adam,
>
> Explanation of the question:
> When the factory is doing the reflection, it can determine the type of
> the property and get its value.  If the type is a collection and the
> value is null, the collection itself needs to be created before any of
> its elements.
>
> If the property is not a collection, the index is "irrelevant", so it
> really does not matter if jxpath passes 0, -1 or anything else.  You
> should be able to determine its relevance by looking at the property
> type.
>
> Another thing.  The createPathAndSetValue method will call createPath
> on every subpath, so, if the path is "/myList[2]/name" and the list
> only has one element, jxpath will call the factory expecting that it
> would create a new element and add it to the list.
>
> I hope this helps.
>
> - Dmitri
>
> --- Adam J Chesney <ad...@multicom.co.uk> wrote:
> > Dmitri,
> >
> > Thanks for your reply.
> >
> > I understand about the backward compatibility issue, no problem.
> > (Although
> > it does strike me as a bit strange that someone would require an
> > index of
> > zero if the target is not an indexed one, I guess you're fighting a
> > losing
> > battle if you are trying to satisfy everyones different requirements
> > :)
> >
> > Answer: I'm not sure I understand your question. Is it not the case
> > that my
> > Factory will only be invoked when the sequence needs to be created?
> > In fact,
> > I just realised, unless I am mistaken, that my factory will be
> > useless if I
> > want to add objects to a sequence that isn't null, because if I
> > execute this
> > line:
> >
> > context.createPathAndSetValue("/myList", new sequence() );
> >
> > before this one:
> >
> > context.createPathAndSetValue("/myList[2]/name", "harry");
> >
> > the Factory will not get invoked (to create the sequence) and
> > therefore I
> > will get an IndexOutOfBoundsException when JXPath trys to retrieve
> > the
> > second element of the list. Oh well, it's all useful learning. As I
> > said, I
> > am still just playing with ideas.
> >
> > I will check out the Clazz stuff. Thanks. The main problem with
> > Castor
> > intergration, as I see it, is that Castor doesn't support Collections
> > as
> > much as it could. The generated classes, even for sequences, do not
> > implement List, which could be an issue. I may end up ditching Castor
> > in
> > favour of Betwixt. I haven't really looked at it yet, but it might
> > provide
> > for better intergration, although I do like working from an XML
> > Schema (with
> > castor). I guess I can't have my cake AND eat it 8].
> >
> > Adam.
> >
> > ----- Original Message -----
> > From: "Dmitri Plotnikov" <dp...@yahoo.com>
> > To: "Jakarta Commons Developers List"
> > <co...@jakarta.apache.org>
> > Sent: Tuesday, February 04, 2003 3:20 PM
> > Subject: Re: [JXPath] creating sequences
> >
> >
> > > Adam,
> > >
> > > Thank you for your kind words.
> > >
> > > The PropertyPointer used to work just like you are suggesting, but
> > then
> > > somebody complained and I changed it to always pass a legitimate
> > index.
> > >  So now it is a backward compatibility issue.
> > >
> > > Question: can't you determine whether you need to create the
> > collection
> > > by simply checking if it exists?  With Castor it would not make
> > sense
> > > to create a collection and leave it empty anyway, right?
> > >
> > > Your GenericFactory is quite impressive.  BTW, check out our new
> > > sandbox "clazz" project.  It standardizes the introspection of
> > those
> > > "add" methods, plural property names and does many other fun
> > things. If
> > > clazz ever climbs out of the sandbox, we will integrate it with
> > jxpath
> > > and provide a customization of Castor.  So the application of
> > jxpath to
> > > Castor will become more natural.
> > >
> > > Best regards,
> > >
> > > - Dmitri
> > >
> > >
> > > --- Adam J Chesney <ad...@multicom.co.uk> wrote:
> > > > Hi,
> > > >
> > > > I am new to JXPath but it looks great, thanks for all your hard
> > work.
> > > > I have just been playing around with it a little as I would like
> > to
> > > > use it in a new project that I am working on. I wanted to
> > implement a
> > > > generic Factory to create objects and I ran into a small snag. I
> > just
> > > > wanted to run this by you. My GenericFactory (attached) is a bit
> > > > rough around the edges but it automatically creates properties
> > using
> > > > reflection to find the appropriate set method on the parent
> > object,
> > > > and then instantiates an instance of the appropriate class
> > (parameter
> > > > type). This works fine for straight beans but using the same
> > method
> > > > for sequences causes a problem because atm it is not possible to
> > > > determine whether or not the target property is a sequence or
> > not. If
> > > > you can determine that you are creating a sequence then it is
> > > > possible (in some circumstances) to determine the type of the
> > objects
> > > > to be added to the newly created sequence, and to add them during
> > the
> > > > construction of the sequence property. This won't work for
> > generic
> > > > Collections, but it will work for custom sequences that implement
> > > > List, which is what I am using (Castor based beans).
> > > >
> > > > By changing line 178 in
> > > >
> > > > org.apache.commons.jxpath.ri.model.beans.PropertyPointer.java
> > > >
> > > > from
> > > >
> > > >      int inx = (index == WHOLE_COLLECTION ? 0 : index);
> > > >
> > > > to
> > > >
> > > >      int inx = (index == WHOLE_COLLECTION ? -1 : index);
> > > >
> > > > I am now able to determine whether or not the target property for
> > > > construction is a sequence and is accessed using an index and I
> > can
> > > > therefore, in the factory, create the required number of objects.
> > > > Previously, it was impossible to tell the difference between
> > /myList
> > > > and /myList[1] because the index passed to the Factory in both
> > cases
> > > > is 0.
> > > >
> > > > So I can now execute calls like:
> > > >
> > > > context.createPathAndSetValue("/myList[2]/name", "harry");
> > > >
> > > > Even though myList is null to start with, the GenericFactory can
> > > > determine that myList is a sequence and it can create 2 objects
> > to
> > > > add into it after creating and sequence and assigning it to the
> > root
> > > > context.
> > > >
> > > > Anyway, I don't think this change should negatively effect anyone
> > and
> > > > so I thought that maybe you could add it to the main tree. If
> > it's
> > > > not possible, then no problem, I can maintain my own version. I
> > guess
> > > > a change like this could potentially cause problems if the
> > Factory
> > > > coding was a bit "lazy".
> > > >
> > > > Anyway, once agin, thanks for this kewl tool.
> > > >
> > > > Warm regards,
> > > >
> > > > Adam Chesney.
> > > >
> > > >
> > > > =====================================================
> > > >
> > > > Tel:   (+44) 117 908 1254 (Direct)
> > > > Mobile (+44) 7780 962 961
> > > > email: adam@multicom.co.uk
> > > >
> > > > This communication is intended solely for the addressee and is
> > > > confidential.
> > > > If you are not the intended recipient, any disclosure, copying,
> > > > distribution
> > > > or any action taken or omitted to be taken in reliance on it, is
> > > > prohibited
> > > > and may be unlawful.
> > > >
> > > > Although this e-mail and any attachments are believed to be free
> > of
> > > > any
> > > > virus, or any other defect which might affect any computer or IT
> > > > system into
> > > > which they are received and opened, it is the responsibility of
> > the
> > > > recipient to ensure that they are virus free and no
> > responsibility is
> > > > accepted by Multicom Products Limited for any loss or damage
> > arising
> > > > in any
> >
> === message truncated ===
>
>
> __________________________________________________
> Do you Yahoo!?
> Yahoo! Mail Plus - Powerful. Affordable. Sign up now.
> http://mailplus.yahoo.com
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: commons-dev-unsubscribe@jakarta.apache.org
> For additional commands, e-mail: commons-dev-help@jakarta.apache.org


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


Re: [JXPath] creating sequences

Posted by Dmitri Plotnikov <dp...@yahoo.com>.
Adam,

Explanation of the question:
When the factory is doing the reflection, it can determine the type of
the property and get its value.  If the type is a collection and the
value is null, the collection itself needs to be created before any of
its elements.

If the property is not a collection, the index is "irrelevant", so it
really does not matter if jxpath passes 0, -1 or anything else.  You
should be able to determine its relevance by looking at the property
type. 

Another thing.  The createPathAndSetValue method will call createPath
on every subpath, so, if the path is "/myList[2]/name" and the list
only has one element, jxpath will call the factory expecting that it
would create a new element and add it to the list.

I hope this helps.

- Dmitri

--- Adam J Chesney <ad...@multicom.co.uk> wrote:
> Dmitri,
> 
> Thanks for your reply.
> 
> I understand about the backward compatibility issue, no problem.
> (Although
> it does strike me as a bit strange that someone would require an
> index of
> zero if the target is not an indexed one, I guess you're fighting a
> losing
> battle if you are trying to satisfy everyones different requirements
> :)
> 
> Answer: I'm not sure I understand your question. Is it not the case
> that my
> Factory will only be invoked when the sequence needs to be created?
> In fact,
> I just realised, unless I am mistaken, that my factory will be
> useless if I
> want to add objects to a sequence that isn't null, because if I
> execute this
> line:
> 
> context.createPathAndSetValue("/myList", new sequence() );
> 
> before this one:
> 
> context.createPathAndSetValue("/myList[2]/name", "harry");
> 
> the Factory will not get invoked (to create the sequence) and
> therefore I
> will get an IndexOutOfBoundsException when JXPath trys to retrieve
> the
> second element of the list. Oh well, it's all useful learning. As I
> said, I
> am still just playing with ideas.
> 
> I will check out the Clazz stuff. Thanks. The main problem with
> Castor
> intergration, as I see it, is that Castor doesn't support Collections
> as
> much as it could. The generated classes, even for sequences, do not
> implement List, which could be an issue. I may end up ditching Castor
> in
> favour of Betwixt. I haven't really looked at it yet, but it might
> provide
> for better intergration, although I do like working from an XML
> Schema (with
> castor). I guess I can't have my cake AND eat it 8].
> 
> Adam.
> 
> ----- Original Message -----
> From: "Dmitri Plotnikov" <dp...@yahoo.com>
> To: "Jakarta Commons Developers List"
> <co...@jakarta.apache.org>
> Sent: Tuesday, February 04, 2003 3:20 PM
> Subject: Re: [JXPath] creating sequences
> 
> 
> > Adam,
> >
> > Thank you for your kind words.
> >
> > The PropertyPointer used to work just like you are suggesting, but
> then
> > somebody complained and I changed it to always pass a legitimate
> index.
> >  So now it is a backward compatibility issue.
> >
> > Question: can't you determine whether you need to create the
> collection
> > by simply checking if it exists?  With Castor it would not make
> sense
> > to create a collection and leave it empty anyway, right?
> >
> > Your GenericFactory is quite impressive.  BTW, check out our new
> > sandbox "clazz" project.  It standardizes the introspection of
> those
> > "add" methods, plural property names and does many other fun
> things. If
> > clazz ever climbs out of the sandbox, we will integrate it with
> jxpath
> > and provide a customization of Castor.  So the application of
> jxpath to
> > Castor will become more natural.
> >
> > Best regards,
> >
> > - Dmitri
> >
> >
> > --- Adam J Chesney <ad...@multicom.co.uk> wrote:
> > > Hi,
> > >
> > > I am new to JXPath but it looks great, thanks for all your hard
> work.
> > > I have just been playing around with it a little as I would like
> to
> > > use it in a new project that I am working on. I wanted to
> implement a
> > > generic Factory to create objects and I ran into a small snag. I
> just
> > > wanted to run this by you. My GenericFactory (attached) is a bit
> > > rough around the edges but it automatically creates properties
> using
> > > reflection to find the appropriate set method on the parent
> object,
> > > and then instantiates an instance of the appropriate class
> (parameter
> > > type). This works fine for straight beans but using the same
> method
> > > for sequences causes a problem because atm it is not possible to
> > > determine whether or not the target property is a sequence or
> not. If
> > > you can determine that you are creating a sequence then it is
> > > possible (in some circumstances) to determine the type of the
> objects
> > > to be added to the newly created sequence, and to add them during
> the
> > > construction of the sequence property. This won't work for
> generic
> > > Collections, but it will work for custom sequences that implement
> > > List, which is what I am using (Castor based beans).
> > >
> > > By changing line 178 in
> > >
> > > org.apache.commons.jxpath.ri.model.beans.PropertyPointer.java
> > >
> > > from
> > >
> > >      int inx = (index == WHOLE_COLLECTION ? 0 : index);
> > >
> > > to
> > >
> > >      int inx = (index == WHOLE_COLLECTION ? -1 : index);
> > >
> > > I am now able to determine whether or not the target property for
> > > construction is a sequence and is accessed using an index and I
> can
> > > therefore, in the factory, create the required number of objects.
> > > Previously, it was impossible to tell the difference between
> /myList
> > > and /myList[1] because the index passed to the Factory in both
> cases
> > > is 0.
> > >
> > > So I can now execute calls like:
> > >
> > > context.createPathAndSetValue("/myList[2]/name", "harry");
> > >
> > > Even though myList is null to start with, the GenericFactory can
> > > determine that myList is a sequence and it can create 2 objects
> to
> > > add into it after creating and sequence and assigning it to the
> root
> > > context.
> > >
> > > Anyway, I don't think this change should negatively effect anyone
> and
> > > so I thought that maybe you could add it to the main tree. If
> it's
> > > not possible, then no problem, I can maintain my own version. I
> guess
> > > a change like this could potentially cause problems if the
> Factory
> > > coding was a bit "lazy".
> > >
> > > Anyway, once agin, thanks for this kewl tool.
> > >
> > > Warm regards,
> > >
> > > Adam Chesney.
> > >
> > >
> > > =====================================================
> > >
> > > Tel:   (+44) 117 908 1254 (Direct)
> > > Mobile (+44) 7780 962 961
> > > email: adam@multicom.co.uk
> > >
> > > This communication is intended solely for the addressee and is
> > > confidential.
> > > If you are not the intended recipient, any disclosure, copying,
> > > distribution
> > > or any action taken or omitted to be taken in reliance on it, is
> > > prohibited
> > > and may be unlawful.
> > >
> > > Although this e-mail and any attachments are believed to be free
> of
> > > any
> > > virus, or any other defect which might affect any computer or IT
> > > system into
> > > which they are received and opened, it is the responsibility of
> the
> > > recipient to ensure that they are virus free and no
> responsibility is
> > > accepted by Multicom Products Limited for any loss or damage
> arising
> > > in any
> 
=== message truncated ===


__________________________________________________
Do you Yahoo!?
Yahoo! Mail Plus - Powerful. Affordable. Sign up now.
http://mailplus.yahoo.com

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


Re: [JXPath] creating sequences

Posted by Adam J Chesney <ad...@multicom.co.uk>.
Dmitri,

Thanks for your reply.

I understand about the backward compatibility issue, no problem. (Although
it does strike me as a bit strange that someone would require an index of
zero if the target is not an indexed one, I guess you're fighting a losing
battle if you are trying to satisfy everyones different requirements :)

Answer: I'm not sure I understand your question. Is it not the case that my
Factory will only be invoked when the sequence needs to be created? In fact,
I just realised, unless I am mistaken, that my factory will be useless if I
want to add objects to a sequence that isn't null, because if I execute this
line:

context.createPathAndSetValue("/myList", new sequence() );

before this one:

context.createPathAndSetValue("/myList[2]/name", "harry");

the Factory will not get invoked (to create the sequence) and therefore I
will get an IndexOutOfBoundsException when JXPath trys to retrieve the
second element of the list. Oh well, it's all useful learning. As I said, I
am still just playing with ideas.

I will check out the Clazz stuff. Thanks. The main problem with Castor
intergration, as I see it, is that Castor doesn't support Collections as
much as it could. The generated classes, even for sequences, do not
implement List, which could be an issue. I may end up ditching Castor in
favour of Betwixt. I haven't really looked at it yet, but it might provide
for better intergration, although I do like working from an XML Schema (with
castor). I guess I can't have my cake AND eat it 8].

Adam.

----- Original Message -----
From: "Dmitri Plotnikov" <dp...@yahoo.com>
To: "Jakarta Commons Developers List" <co...@jakarta.apache.org>
Sent: Tuesday, February 04, 2003 3:20 PM
Subject: Re: [JXPath] creating sequences


> Adam,
>
> Thank you for your kind words.
>
> The PropertyPointer used to work just like you are suggesting, but then
> somebody complained and I changed it to always pass a legitimate index.
>  So now it is a backward compatibility issue.
>
> Question: can't you determine whether you need to create the collection
> by simply checking if it exists?  With Castor it would not make sense
> to create a collection and leave it empty anyway, right?
>
> Your GenericFactory is quite impressive.  BTW, check out our new
> sandbox "clazz" project.  It standardizes the introspection of those
> "add" methods, plural property names and does many other fun things. If
> clazz ever climbs out of the sandbox, we will integrate it with jxpath
> and provide a customization of Castor.  So the application of jxpath to
> Castor will become more natural.
>
> Best regards,
>
> - Dmitri
>
>
> --- Adam J Chesney <ad...@multicom.co.uk> wrote:
> > Hi,
> >
> > I am new to JXPath but it looks great, thanks for all your hard work.
> > I have just been playing around with it a little as I would like to
> > use it in a new project that I am working on. I wanted to implement a
> > generic Factory to create objects and I ran into a small snag. I just
> > wanted to run this by you. My GenericFactory (attached) is a bit
> > rough around the edges but it automatically creates properties using
> > reflection to find the appropriate set method on the parent object,
> > and then instantiates an instance of the appropriate class (parameter
> > type). This works fine for straight beans but using the same method
> > for sequences causes a problem because atm it is not possible to
> > determine whether or not the target property is a sequence or not. If
> > you can determine that you are creating a sequence then it is
> > possible (in some circumstances) to determine the type of the objects
> > to be added to the newly created sequence, and to add them during the
> > construction of the sequence property. This won't work for generic
> > Collections, but it will work for custom sequences that implement
> > List, which is what I am using (Castor based beans).
> >
> > By changing line 178 in
> >
> > org.apache.commons.jxpath.ri.model.beans.PropertyPointer.java
> >
> > from
> >
> >      int inx = (index == WHOLE_COLLECTION ? 0 : index);
> >
> > to
> >
> >      int inx = (index == WHOLE_COLLECTION ? -1 : index);
> >
> > I am now able to determine whether or not the target property for
> > construction is a sequence and is accessed using an index and I can
> > therefore, in the factory, create the required number of objects.
> > Previously, it was impossible to tell the difference between /myList
> > and /myList[1] because the index passed to the Factory in both cases
> > is 0.
> >
> > So I can now execute calls like:
> >
> > context.createPathAndSetValue("/myList[2]/name", "harry");
> >
> > Even though myList is null to start with, the GenericFactory can
> > determine that myList is a sequence and it can create 2 objects to
> > add into it after creating and sequence and assigning it to the root
> > context.
> >
> > Anyway, I don't think this change should negatively effect anyone and
> > so I thought that maybe you could add it to the main tree. If it's
> > not possible, then no problem, I can maintain my own version. I guess
> > a change like this could potentially cause problems if the Factory
> > coding was a bit "lazy".
> >
> > Anyway, once agin, thanks for this kewl tool.
> >
> > Warm regards,
> >
> > Adam Chesney.
> >
> >
> > =====================================================
> >
> > Tel:   (+44) 117 908 1254 (Direct)
> > Mobile (+44) 7780 962 961
> > email: adam@multicom.co.uk
> >
> > This communication is intended solely for the addressee and is
> > confidential.
> > If you are not the intended recipient, any disclosure, copying,
> > distribution
> > or any action taken or omitted to be taken in reliance on it, is
> > prohibited
> > and may be unlawful.
> >
> > Although this e-mail and any attachments are believed to be free of
> > any
> > virus, or any other defect which might affect any computer or IT
> > system into
> > which they are received and opened, it is the responsibility of the
> > recipient to ensure that they are virus free and no responsibility is
> > accepted by Multicom Products Limited for any loss or damage arising
> > in any
> > way from receipt or use thereof.
> > > package test;
> >
> > import org.apache.commons.jxpath.*;
> > import java.lang.reflect.*;
> >
> > /**
> >  * <p>Title: </p>
> >  * <p>Description: </p>
> >  * <p>Copyright: Copyright (c) 2003</p>
> >  * <p>Company: </p>
> >  * @author Adam J Chesney
> >  * @version 1.0
> >  */
> >
> > public class GenericFactory extends AbstractFactory
> > {
> >
> >   public boolean createObject(JXPathContext context, Pointer pointer,
> > Object parent, String name, int index)
> >   {
> >     try
> >     {
> >       // grab the parents class
> >       Class parent_cls = parent.getClass();
> >
> >       // grab the list of methods for the parent class
> >       Method[] methods = parent_cls.getMethods();
> >
> >       // iterate backwards through the methods until we find the
> > first
> >       // 'set' or 'add' method which matches the name property and
> > that has just
> >       // one parameter
> >       for (int i = methods.length-1; i > -1; i--)
> >       {
> >         String mName = methods[i].getName();
> > if ( mName.startsWith("set") || mName.startsWith("add") )
> > {
> >   if ( mName.substring(3).equals( name.substring(0,1).toUpperCase()
> > + name.substring(1) ) )
> >   {
> >     if ( methods[i].getParameterTypes().length == 1 )
> >     {
> >       // we found a matching method, so we grab the class of the
> > parameter
> >       Class target_cls = methods[i].getParameterTypes()[0];
> >
> >       // create new one (must have a null constructor)
> >       Object obj = target_cls.newInstance();
> >
> >       // invoke the add or set method with the new property on the
> > parent
> >       methods[i].invoke( parent, new Object[]{obj} );
> >
> >       // if the index is 0 or greater then this must be a sequence
> >       if ( index > -1 )
> >       {
> > // grab the methods of the property
> > Method[] meth = target_cls.getMethods();
> >
> > // again iterate backwards through the methods looking for the
> > first
> > // add method with one parameter
> > // note: we iterate backwards becuase we are more likely to
> > encounter
> > // a specialized bean method sooner
> > for (int j = meth.length-1; j >-1; j--)
> > {
> >   String mn = meth[j].getName();
> >   if (mn.startsWith("add") && meth[j].getParameterTypes().length ==
> > 1 )
> >   {
> >     // found an add method, so we grab the parameter type
> >     Class new_cls = meth[j].getParameterTypes()[0];
> >     for (int k = 0; k <= index; k++)
> >     {
> >       // and we add enough new objects to the collection to satisfy
> > the index
> >       meth[j].invoke( obj, new Object[]{new_cls.newInstance()} );
> >     }
> >     break;
> >   }
> > }
> >       }
> >
> >       return true;
> >     }
> >   }
> > }
> >       }
> >     }
> >     catch (Exception e1)
> >     {
> >       e1.printStackTrace();
> >     }
> >     return false;
> >   }
> > }
> > >
> ---------------------------------------------------------------------
> > To unsubscribe, e-mail: commons-dev-unsubscribe@jakarta.apache.org
> > For additional commands, e-mail: commons-dev-help@jakarta.apache.org
>
>
> __________________________________________________
> Do you Yahoo!?
> Yahoo! Mail Plus - Powerful. Affordable. Sign up now.
> http://mailplus.yahoo.com
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: commons-dev-unsubscribe@jakarta.apache.org
> For additional commands, e-mail: commons-dev-help@jakarta.apache.org


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


Re: [JXPath] creating sequences

Posted by Dmitri Plotnikov <dp...@yahoo.com>.
Adam,

Thank you for your kind words.

The PropertyPointer used to work just like you are suggesting, but then
somebody complained and I changed it to always pass a legitimate index.
 So now it is a backward compatibility issue.

Question: can't you determine whether you need to create the collection
by simply checking if it exists?  With Castor it would not make sense
to create a collection and leave it empty anyway, right? 

Your GenericFactory is quite impressive.  BTW, check out our new
sandbox "clazz" project.  It standardizes the introspection of those
"add" methods, plural property names and does many other fun things. If
clazz ever climbs out of the sandbox, we will integrate it with jxpath
and provide a customization of Castor.  So the application of jxpath to
Castor will become more natural.

Best regards,

- Dmitri


--- Adam J Chesney <ad...@multicom.co.uk> wrote:
> Hi,
> 
> I am new to JXPath but it looks great, thanks for all your hard work.
> I have just been playing around with it a little as I would like to
> use it in a new project that I am working on. I wanted to implement a
> generic Factory to create objects and I ran into a small snag. I just
> wanted to run this by you. My GenericFactory (attached) is a bit
> rough around the edges but it automatically creates properties using
> reflection to find the appropriate set method on the parent object,
> and then instantiates an instance of the appropriate class (parameter
> type). This works fine for straight beans but using the same method
> for sequences causes a problem because atm it is not possible to
> determine whether or not the target property is a sequence or not. If
> you can determine that you are creating a sequence then it is
> possible (in some circumstances) to determine the type of the objects
> to be added to the newly created sequence, and to add them during the
> construction of the sequence property. This won't work for generic
> Collections, but it will work for custom sequences that implement
> List, which is what I am using (Castor based beans). 
> 
> By changing line 178 in 
> 
> org.apache.commons.jxpath.ri.model.beans.PropertyPointer.java
> 
> from
> 
>      int inx = (index == WHOLE_COLLECTION ? 0 : index);
> 
> to
> 
>      int inx = (index == WHOLE_COLLECTION ? -1 : index);
> 
> I am now able to determine whether or not the target property for
> construction is a sequence and is accessed using an index and I can
> therefore, in the factory, create the required number of objects.
> Previously, it was impossible to tell the difference between /myList
> and /myList[1] because the index passed to the Factory in both cases
> is 0.
> 
> So I can now execute calls like:
> 
> context.createPathAndSetValue("/myList[2]/name", "harry");
> 
> Even though myList is null to start with, the GenericFactory can
> determine that myList is a sequence and it can create 2 objects to
> add into it after creating and sequence and assigning it to the root
> context.
> 
> Anyway, I don't think this change should negatively effect anyone and
> so I thought that maybe you could add it to the main tree. If it's
> not possible, then no problem, I can maintain my own version. I guess
> a change like this could potentially cause problems if the Factory
> coding was a bit "lazy".
> 
> Anyway, once agin, thanks for this kewl tool.
> 
> Warm regards,
> 
> Adam Chesney.
> 
> 
> =====================================================
>  
> Tel:   (+44) 117 908 1254 (Direct)
> Mobile (+44) 7780 962 961
> email: adam@multicom.co.uk
>  
> This communication is intended solely for the addressee and is
> confidential.
> If you are not the intended recipient, any disclosure, copying,
> distribution
> or any action taken or omitted to be taken in reliance on it, is
> prohibited
> and may be unlawful.
>  
> Although this e-mail and any attachments are believed to be free of
> any
> virus, or any other defect which might affect any computer or IT
> system into
> which they are received and opened, it is the responsibility of the
> recipient to ensure that they are virus free and no responsibility is
> accepted by Multicom Products Limited for any loss or damage arising
> in any
> way from receipt or use thereof.
> > package test;
> 
> import org.apache.commons.jxpath.*;
> import java.lang.reflect.*;
> 
> /**
>  * <p>Title: </p>
>  * <p>Description: </p>
>  * <p>Copyright: Copyright (c) 2003</p>
>  * <p>Company: </p>
>  * @author Adam J Chesney
>  * @version 1.0
>  */
> 
> public class GenericFactory extends AbstractFactory
> {
> 
>   public boolean createObject(JXPathContext context, Pointer pointer,
> Object parent, String name, int index)
>   {
>     try
>     {
>       // grab the parents class
>       Class parent_cls = parent.getClass();
> 
>       // grab the list of methods for the parent class
>       Method[] methods = parent_cls.getMethods();
> 
>       // iterate backwards through the methods until we find the
> first
>       // 'set' or 'add' method which matches the name property and
> that has just
>       // one parameter
>       for (int i = methods.length-1; i > -1; i--)
>       {
>         String mName = methods[i].getName();
> 	if ( mName.startsWith("set") || mName.startsWith("add") )
> 	{
> 	  if ( mName.substring(3).equals( name.substring(0,1).toUpperCase()
> + name.substring(1) ) )
> 	  {
> 	    if ( methods[i].getParameterTypes().length == 1 )
> 	    {
> 	      // we found a matching method, so we grab the class of the
> parameter
> 	      Class target_cls = methods[i].getParameterTypes()[0];
> 
> 	      // create new one (must have a null constructor)
> 	      Object obj = target_cls.newInstance();
> 
> 	      // invoke the add or set method with the new property on the
> parent
> 	      methods[i].invoke( parent, new Object[]{obj} );
> 
> 	      // if the index is 0 or greater then this must be a sequence
> 	      if ( index > -1 )
> 	      {
> 		// grab the methods of the property
> 		Method[] meth = target_cls.getMethods();
> 
> 		// again iterate backwards through the methods looking for the
> first
> 		// add method with one parameter
> 		// note: we iterate backwards becuase we are more likely to
> encounter
> 		// a specialized bean method sooner
> 		for (int j = meth.length-1; j >-1; j--)
> 		{
> 		  String mn = meth[j].getName();
> 		  if (mn.startsWith("add") && meth[j].getParameterTypes().length ==
> 1 )
> 		  {
> 		    // found an add method, so we grab the parameter type
> 		    Class new_cls = meth[j].getParameterTypes()[0];
> 		    for (int k = 0; k <= index; k++)
> 		    {
> 		      // and we add enough new objects to the collection to satisfy
> the index
> 		      meth[j].invoke( obj, new Object[]{new_cls.newInstance()} );
> 		    }
> 		    break;
> 		  }
> 		}
> 	      }
> 
> 	      return true;
> 	    }
> 	  }
> 	}
>       }
>     }
>     catch (Exception e1)
>     {
>       e1.printStackTrace();
>     }
>     return false;
>   }
> }
> >
---------------------------------------------------------------------
> To unsubscribe, e-mail: commons-dev-unsubscribe@jakarta.apache.org
> For additional commands, e-mail: commons-dev-help@jakarta.apache.org


__________________________________________________
Do you Yahoo!?
Yahoo! Mail Plus - Powerful. Affordable. Sign up now.
http://mailplus.yahoo.com

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