You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@cocoon.apache.org by Hugo Burm <hu...@xs4all.nl> on 2003/08/20 20:27:48 UTC

Woody, maps, and repeaters


I am trying to use the Woody sample that uses a Java bean for its binding
(form2bean.flow).
I want to store the contacts in this example in a map instead of in a list,
but in this case the contacts are not displayed (one empty contact instead
of 4), and submit gives an insert error for "contacts[1]).
I had an almost identical problem with JXForms.
When I skip the Woody form in my flowscript, and just show the result page
(form2_jx.xml), all my contacts are displayed OK. So JXPath knows how to
iterate over a Map.
I dived into the Woody sources and an obvious place to look is the Java
class "RepeaterJXPathBinding.java" and especially the line
        Iterator rowPointers =
repeaterContext.iteratePointers(this.rowPath);
in the function "loadFormFromModel" in this class.
Can someone tell me whether this function iteratePointers() gives me the
expected result: an iterator over the Map (this.rowPath)? I did check the
JXPath docs and tried Google. I guess the answer is no, and because the
iterator seems to have one value, I guess it returns one object with a list
of keys and a list of values.


Thanks

Hugo Burm




Re: Woody, maps, and repeaters

Posted by Marc Portier <mp...@outerthought.org>.
oops!

considering:

> 
> <myBean>
>   <address>
>     <hugo><street/><city/></hugo>
>     <marc><street/><city/></marc>
>     <bruno><street/><city/></bruno>
>   </address>
> </myBean>
> 

this:

> 
> and I'm not sure but probably
> $myBean/* --> would give you the iteration of the 3 address nodes
> 

should have been $myBean/address/* I guess (warning: untested 
with jxpath on Java Beans, but is what I would expect)

-marc=
-- 
Marc Portier                            http://outerthought.org/
Outerthought - Open Source, Java & XML Competence Support Center
Read my weblog at              http://radio.weblogs.com/0116284/
mpo@outerthought.org                              mpo@apache.org


Re: Woody, maps, and repeaters

Posted by Marc Portier <mp...@outerthought.org>.

Hugo Burm wrote:
> 
>>Marc Portier wrote:
>>
>>
>>Hugo Burm wrote:
>>
>>>Hello Marc,
>>>
>>
>>sorry for the late reply...
>>
>>
>>>Ok. Let me explain. Maps are sometimes much more convenient than Lists
>>>(let's skip a discussion on that one). So I have two classes:
>>
>><SKIP/>
>>
>>Well, for what its worth the not to have discussion is probably
>>not on LIST vs MAP but MAP vs SET :-)
>>
>>I'ld personally would have tackled this with a HashSet of
>>contacts and adding the appropriate hashcode() and equals()
>>methods to the HContact so its very own id would serve as the
>>fast lookup in the Set...
>>
>>(but it doesn't really change much the real issue here)
>>
>>
>>>What I want to do is: create a Map of contacts in HForm2Bean and access
>>>these contacts with a key "id".
>>>This key is also stored in one of the fields of HContact (id). The field
>>>that is the key, should be one of the configuration parameters
>>
>>of the Woody
>>
>>>repeater.
>>
>>yep.
>>
>>
>>>This solves your question "which key to use?".
>>
>>not really, it doesn't solve the question on the way back, unless
>>you expect the id's to be edited by hand?
>>
>>(which would surely require another RepeaterBinding implementation)
>>
> 
> 
> 
> 
> I tried to ommit the persistence topic, but many of the issues above have to
> do with the Hibernate framework I am using. E.g. the id is generated by
> Hibernate. This works OK for the list implementation in Woody. The Woody
> framework detects a contact that is inserted because its id is null. Then,
> Hibernate generates the id when saving the contact to hard disk.
> 
> About lists, maps, and sets: Hibernate has four mappings: the three I just
> mentioned, plus something called a "bag". So people like me will keep on
> asking for repeaters for these three types. JDO 2.0 builds on Hibernate. So
> I will not be the last one asking for this.
> 
> 

sure, and sorry if I ever gave you the impression that you were 
asking for 'bad' or useless things... I highly welcome any use 
case that shows an itch to scratch... at the time I just wanted 
some more clarification

thx for explaining the id generation thing, it adds to the food 
for thought on this

> 
>>>file "binding_example.js" in such a way that a bean and a
>>
>>number of contacts
>>
>>>are created; the editing is skipped; and we go directly to your pipeline
>>>"form2bean-success-pipeline", the form2_jx.xml form is called.
>>
>>This contains
>>
>>>the loop:
>>>      <jx:forEach var="item" items="${form2bean.contacts}">
>>>        <tr>
>>>          <td>${item.id}</td>
>>>          <td>${item.firstName}</td>
>>>          <td>${item.lastName}</td>
>>>					<skip/>
>>>        </tr>
>>>      </jx:forEach>
>>>
>>>This loops shows the correct results when I use a map instead of a list!
>>
>>hm, my turn to be not convinced: above uses the ${..} expressions
>>inside jx and not the #{..}
>>
>>${..} in jx are evaluated by jexl
>>#{..} are covered by jxpath
>>
>>so we're looking at a horse of an entirely different color here.
>>
> 
> 
> 
> 
> OK, may be I had too much sunshine the last couple of weeks. I did a post
> myself about the difference between # and $ a few weeks ago which covered
> exactly this problem:
> http://marc.theaimsgroup.com/?l=xml-cocoon-dev&m=106050576128633&w=2
> I checked the JXPath docs and your explanation appears to be correct. Sorry.
> 
> 

no need to appologise, this confuses me all the time, in fact you 
had me doubthing my little technique for a while... so spotting 
the $# just gave me back some mental sanity :-)

> 
>>
>>Back to your issue: how to edit these beans with Woody/Binding?
>>
>>I would need some more time to get into it more deeply, so I
>>wouldn't mind if somebody with more current slack hacks this up
>>ans shares this
>>
>>Hugo, how urgent is this for you?
>>
>>AFAICS this needs a different RepeaterBinding of some sort that
>>is not that much different to the existing one, just that
>>
>>
> 
> 
> 
> I hacked the Woody RepeaterBinding myself and solved my own urgent problem.
> Listing a map of contacts is working. Updating is working. Adding and
> deleting contacts is something I don't need at the moment (off course my
> real world problem has nothing to do with this form2bean and contact
> classes), but I will try to add this, and send the results to you.
> 

thx chap, would surely like to see it, if you could hack it up as 
a an extra woody-sample (damn: there goes the hibernate-licensing 
issue again) that would be really great

you got this up on my todo list, if I reach this before you got 
the time to pollish up I might be asking for just sending what 
you have at the time, if you don't mind

> Thanks.
> 
> 
> Hugo Burm
> 

regards,
-marc=
-- 
Marc Portier                            http://outerthought.org/
Outerthought - Open Source, Java & XML Competence Support Center
Read my weblog at              http://radio.weblogs.com/0116284/
mpo@outerthought.org                              mpo@apache.org


RE: Woody, maps, and repeaters

Posted by Hugo Burm <hu...@xs4all.nl>.

> Marc Portier wrote:
>
>
> Hugo Burm wrote:
> > Hello Marc,
> >
>
> sorry for the late reply...
>
> > Ok. Let me explain. Maps are sometimes much more convenient than Lists
> > (let's skip a discussion on that one). So I have two classes:
> <SKIP/>
>
> Well, for what its worth the not to have discussion is probably
> not on LIST vs MAP but MAP vs SET :-)
>
> I'ld personally would have tackled this with a HashSet of
> contacts and adding the appropriate hashcode() and equals()
> methods to the HContact so its very own id would serve as the
> fast lookup in the Set...
>
> (but it doesn't really change much the real issue here)
>
> > What I want to do is: create a Map of contacts in HForm2Bean and access
> > these contacts with a key "id".
> > This key is also stored in one of the fields of HContact (id). The field
> > that is the key, should be one of the configuration parameters
> of the Woody
> > repeater.
>
> yep.
>
> > This solves your question "which key to use?".
>
> not really, it doesn't solve the question on the way back, unless
> you expect the id's to be edited by hand?
>
> (which would surely require another RepeaterBinding implementation)
>



I tried to ommit the persistence topic, but many of the issues above have to
do with the Hibernate framework I am using. E.g. the id is generated by
Hibernate. This works OK for the list implementation in Woody. The Woody
framework detects a contact that is inserted because its id is null. Then,
Hibernate generates the id when saving the contact to hard disk.

About lists, maps, and sets: Hibernate has four mappings: the three I just
mentioned, plus something called a "bag". So people like me will keep on
asking for repeaters for these three types. JDO 2.0 builds on Hibernate. So
I will not be the last one asking for this.


> > file "binding_example.js" in such a way that a bean and a
> number of contacts
> > are created; the editing is skipped; and we go directly to your pipeline
> > "form2bean-success-pipeline", the form2_jx.xml form is called.
> This contains
> > the loop:
> >       <jx:forEach var="item" items="${form2bean.contacts}">
> >         <tr>
> >           <td>${item.id}</td>
> >           <td>${item.firstName}</td>
> >           <td>${item.lastName}</td>
> > 					<skip/>
> >         </tr>
> >       </jx:forEach>
> >
> > This loops shows the correct results when I use a map instead of a list!
>
> hm, my turn to be not convinced: above uses the ${..} expressions
> inside jx and not the #{..}
>
> ${..} in jx are evaluated by jexl
> #{..} are covered by jxpath
>
> so we're looking at a horse of an entirely different color here.
>



OK, may be I had too much sunshine the last couple of weeks. I did a post
myself about the difference between # and $ a few weeks ago which covered
exactly this problem:
http://marc.theaimsgroup.com/?l=xml-cocoon-dev&m=106050576128633&w=2
I checked the JXPath docs and your explanation appears to be correct. Sorry.


>
>
> Back to your issue: how to edit these beans with Woody/Binding?
>
> I would need some more time to get into it more deeply, so I
> wouldn't mind if somebody with more current slack hacks this up
> ans shares this
>
> Hugo, how urgent is this for you?
>
> AFAICS this needs a different RepeaterBinding of some sort that
> is not that much different to the existing one, just that
>
>


I hacked the Woody RepeaterBinding myself and solved my own urgent problem.
Listing a map of contacts is working. Updating is working. Adding and
deleting contacts is something I don't need at the moment (off course my
real world problem has nothing to do with this form2bean and contact
classes), but I will try to add this, and send the results to you.

Thanks.


Hugo Burm


Re: Woody, maps, and repeaters

Posted by Marc Portier <mp...@outerthought.org>.

Hugo Burm wrote:
> Hello Marc,
> 

sorry for the late reply...

> Ok. Let me explain. Maps are sometimes much more convenient than Lists
> (let's skip a discussion on that one). So I have two classes:
> 
> public class HContact {
>     private String id;
>     private String firstName;
>     private String lastName;
>     private String phone;
>     private String email;
> <skip>getter/setter methods </skip>
> }
> 
> public class HForm2Bean {
>     private String email;
>     private String phoneCountry;
>     private String phoneZone;
>     private String phoneNumber;
>     private String ipAddress;
>     private Date birthday;
>     private int aNumber;
>     private Map contacts = new HashMap();
> <skip>getter/setter methods </skip>
> }
> 
> These classes are identical to the Woody examples apart from one line in
> (H)Form2Bean:
> Woody Sample:    private Collection contacts = new ArrayList();
> 

Well, for what its worth the not to have discussion is probably 
not on LIST vs MAP but MAP vs SET :-)

I'ld personally would have tackled this with a HashSet of 
contacts and adding the appropriate hashcode() and equals() 
methods to the HContact so its very own id would serve as the 
fast lookup in the Set...

(but it doesn't really change much the real issue here)

> What I want to do is: create a Map of contacts in HForm2Bean and access
> these contacts with a key "id".
> This key is also stored in one of the fields of HContact (id). The field
> that is the key, should be one of the configuration parameters of the Woody
> repeater.

yep.

> This solves your question "which key to use?".

not really, it doesn't solve the question on the way back, unless 
you expect the id's to be edited by hand?

(which would surely require another RepeaterBinding implementation)

> So what I need is a Woody Form to edit these beans. As you have found out, I
> dived into this problem myself. But your company knows a lot more about the
> Woody internals than I do.
> 

our goal is to achieve the opposite for sure

> 
> About your explanation of LIST vesus MAP: Thanks. But I am not convinced.

it's just the technique I use to understand how jxpath is looking 
at stuff

> When I change your function "function form2bean(form)" in the Woody sample

(just for completeness: it isn't mine)

> file "binding_example.js" in such a way that a bean and a number of contacts
> are created; the editing is skipped; and we go directly to your pipeline
> "form2bean-success-pipeline", the form2_jx.xml form is called. This contains
> the loop:
>       <jx:forEach var="item" items="${form2bean.contacts}">
>         <tr>
>           <td>${item.id}</td>
>           <td>${item.firstName}</td>
>           <td>${item.lastName}</td>
> 					<skip/>
>         </tr>
>       </jx:forEach>
> 
> This loops shows the correct results when I use a map instead of a list!

hm, my turn to be not convinced: above uses the ${..} expressions 
inside jx and not the #{..}

${..} in jx are evaluated by jexl
#{..} are covered by jxpath

so we're looking at a horse of an entirely different color here.

the binding files are using jxpath, and as far as I can see those 
would need a different notation for maps vs lists

> I think this could never happen if your XML layout for a map representation,
> shown below, is correct.
> <myBean>
>    <address>
>      <hugo><street/><city/></hugo>
>      <marc><street/><city/></marc>
>      <bruno><street/><city/></bruno>
>    </address>
> </myBean>
> 
> Or translated to the contacts example:
> <myBean>
>    <contacts>
>      <id1><id/><firstname/><lastname/></id1>
>      <id2><id/><firstname/><lastname/></id2>
>      <id3><id/><firstname/><lastname/></id3>
>    </contacts>
> </myBean>
> 
> When I read your second ("oops") email, the map iteration path is now
> identical to the list iteration path. But how can the <jx:foreach> loop skip
> the extra level (the key, e.g. <hugo>, <marc>, or <id1>,<id2> etc) of the
> iterated items?
> 

as above: it uses jexl
my xml-view of things only helps to write down the (j)xpath 
expressions

> Sorry for pinpointing on this jxpath syntax, but a number of people on this
> list have spent hours trying with some kind of trial-and-error method to
> find out how these beans and relations are mapped to XML by jxpath (I am one
> of them). So any comment that makes this issue more clear is appreciated.
> 

well, the first confusion to get rid off is the $ versus # :-)

only when you get into the # you have to think about how to get 
the jxpath right

(first help there is of course the jxpath website, secondly and 
just for me this 'look-as-xml' technique has helped quite often)



Back to your issue: how to edit these beans with Woody/Binding?

I would need some more time to get into it more deeply, so I 
wouldn't mind if somebody with more current slack hacks this up 
ans shares this

Hugo, how urgent is this for you?

AFAICS this needs a different RepeaterBinding of some sort that 
is not that much different to the existing one, just that

1/ the current logic for deciding if the row was new, removed or 
updated will need to change, and I'll be assuming that the new 
id's are entered manually (probably removing all and rebuilding 
all is the easier strategy here)

2/ it shouldn't use the [] syntax

3/ not sure yet how this could reuse the factory-technique of the 
current <on-insert>

and other stuff that comes up when one actually starts coding this

HTH,
-marc=

> Thanks
> 
> Hugo Burm
> 
> 
> 
>>-----Original Message-----
>>From: Marc Portier [mailto:mpo@outerthought.org]
>>Sent: Thursday, August 21, 2003 12:33 PM
>>To: dev@cocoon.apache.org
>>Subject: Re: Woody, maps, and repeaters
>>
>>
>>
>>
>>Hugo Burm wrote:
>>
>>>I am trying to use the Woody sample that uses a Java bean for
>>
>>its binding
>>
>>>(form2bean.flow).
>>>I want to store the contacts in this example in a map instead
>>
>>of in a list,
>>
>>hm, the biggest problem I see with this 'storing in Map' is:
>>"using which key?"
>>
>>Maybe you should elaborate on your use case a bit. (Sorry, I
>>still have to check up on your recent wiki page and accompanied
>>zip.  In any case an upfront thx for sharing that!)
>>
>>
>>>but in this case the contacts are not displayed (one empty
>>
>>contact instead
>>
>>>of 4), and submit gives an insert error for "contacts[1]).
>>>I had an almost identical problem with JXForms
>>>When I skip the Woody form in my flowscript, and just show the
>>
>>result page
>>
>>>(form2_jx.xml), all my contacts are displayed OK. So JXPath knows how to
>>>iterate over a Map.
>>
>>Could you show how your bean looks like?
>>And what is in it?
>>
>>
>>>I dived into the Woody sources and an obvious place to look is the Java
>>>class "RepeaterJXPathBinding.java" and especially the line
>>>        Iterator rowPointers =
>>>repeaterContext.iteratePointers(this.rowPath);
>>
>>yep.
>>
>>
>>>in the function "loadFormFromModel" in this class.
>>
>>this is for the binding from the bean to the form
>>
>>as explained above the trouble I see is with binding back from
>>the form to the bean (which key to use?)
>>
>>
>>>Can someone tell me whether this function iteratePointers() gives me the
>>>expected result: an iterator over the Map (this.rowPath)? I did
>>
>>check the
>>
>>>JXPath docs and tried Google. I guess the answer is no, and because the
>>>iterator seems to have one value, I guess it returns one object
>>
>>with a list
>>
>>>of keys and a list of values.
>>>
>>
>>I'm not completely sure what your trying to say here (or do in
>>general) but there is afaik a difference in how jxpath looks to
>>lists versus maps
>>
>>LISTS
>>suppose myBean.getAddress returns a List then actually jxpath
>>looks at your bean as if it would be an XML structure looking like
>><myBean>
>>   <address><street/><city/></address>
>>   <address><street/><city/></address>
>>   <address><street/><city/></address>
>></myBean>
>>
>>leaving you with expressions like
>>$myBean/address[1]/street --> the street of the first address in
>>the list, something equivalent to
>>((Address)myBean.getAddress.get(0)).getStreet()
>>
>>while $myBean/address --> iteration of the 3 address nodes
>>
>>
>>MAPS
>>suppose myBean.getAddress returns a Map with 3 keys say "hugo",
>>"marc" and "bruno" then actually jxpath looks at your bean as if
>>it would be an XML structure looking like
>><myBean>
>>   <address>
>>     <hugo><street/><city/></hugo>
>>     <marc><street/><city/></marc>
>>     <bruno><street/><city/></bruno>
>>   </address>
>></myBean>
>>
>>leaving you with expressions like
>>$myBean/address[1]/street --> returning nothing
>>$myBean/address/hugo/street --> returning the street of the first
>>address, ie equivalent to
>>((Address)myBean.getAddress.get("hugo")).getStreet()
>>
>>and I'm not sure but probably
>>$myBean/* --> would give you the iteration of the 3 address nodes
>>
>>
>>in any case, I see some mismatches that would make the current
>>RepaterBinding implementation not suitable for these Maps (since
>>they are quite directed to the Lists, using the [index] notation
>>and all)
>>
>>however, if you can explain what sort of binding you would expect
>>to be happening (in both bean and XML worlds) we can easily go
>>for an extra MapRepeater binding or something...
>>
>>regards,
>>-marc=
>>PS: a bit swamped, will do a best effort to follow up though
>>--
>>Marc Portier                            http://outerthought.org/
>>Outerthought - Open Source, Java & XML Competence Support Center
>>Read my weblog at              http://radio.weblogs.com/0116284/
>>mpo@outerthought.org                              mpo@apache.org
>>
>>
> 
> 
> 

-- 
Marc Portier                            http://outerthought.org/
Outerthought - Open Source, Java & XML Competence Support Center
Read my weblog at              http://radio.weblogs.com/0116284/
mpo@outerthought.org                              mpo@apache.org


RE: Woody, maps, and repeaters

Posted by Hugo Burm <hu...@xs4all.nl>.
Hello Marc,

Ok. Let me explain. Maps are sometimes much more convenient than Lists
(let's skip a discussion on that one). So I have two classes:

public class HContact {
    private String id;
    private String firstName;
    private String lastName;
    private String phone;
    private String email;
<skip>getter/setter methods </skip>
}

public class HForm2Bean {
    private String email;
    private String phoneCountry;
    private String phoneZone;
    private String phoneNumber;
    private String ipAddress;
    private Date birthday;
    private int aNumber;
    private Map contacts = new HashMap();
<skip>getter/setter methods </skip>
}

These classes are identical to the Woody examples apart from one line in
(H)Form2Bean:
Woody Sample:    private Collection contacts = new ArrayList();

What I want to do is: create a Map of contacts in HForm2Bean and access
these contacts with a key "id".
This key is also stored in one of the fields of HContact (id). The field
that is the key, should be one of the configuration parameters of the Woody
repeater.
This solves your question "which key to use?".
So what I need is a Woody Form to edit these beans. As you have found out, I
dived into this problem myself. But your company knows a lot more about the
Woody internals than I do.


About your explanation of LIST vesus MAP: Thanks. But I am not convinced.
When I change your function "function form2bean(form)" in the Woody sample
file "binding_example.js" in such a way that a bean and a number of contacts
are created; the editing is skipped; and we go directly to your pipeline
"form2bean-success-pipeline", the form2_jx.xml form is called. This contains
the loop:
      <jx:forEach var="item" items="${form2bean.contacts}">
        <tr>
          <td>${item.id}</td>
          <td>${item.firstName}</td>
          <td>${item.lastName}</td>
					<skip/>
        </tr>
      </jx:forEach>

This loops shows the correct results when I use a map instead of a list!
I think this could never happen if your XML layout for a map representation,
shown below, is correct.
<myBean>
   <address>
     <hugo><street/><city/></hugo>
     <marc><street/><city/></marc>
     <bruno><street/><city/></bruno>
   </address>
</myBean>

Or translated to the contacts example:
<myBean>
   <contacts>
     <id1><id/><firstname/><lastname/></id1>
     <id2><id/><firstname/><lastname/></id2>
     <id3><id/><firstname/><lastname/></id3>
   </contacts>
</myBean>

When I read your second ("oops") email, the map iteration path is now
identical to the list iteration path. But how can the <jx:foreach> loop skip
the extra level (the key, e.g. <hugo>, <marc>, or <id1>,<id2> etc) of the
iterated items?

Sorry for pinpointing on this jxpath syntax, but a number of people on this
list have spent hours trying with some kind of trial-and-error method to
find out how these beans and relations are mapped to XML by jxpath (I am one
of them). So any comment that makes this issue more clear is appreciated.

Thanks

Hugo Burm


> -----Original Message-----
> From: Marc Portier [mailto:mpo@outerthought.org]
> Sent: Thursday, August 21, 2003 12:33 PM
> To: dev@cocoon.apache.org
> Subject: Re: Woody, maps, and repeaters
>
>
>
>
> Hugo Burm wrote:
> >
> > I am trying to use the Woody sample that uses a Java bean for
> its binding
> > (form2bean.flow).
> > I want to store the contacts in this example in a map instead
> of in a list,
>
> hm, the biggest problem I see with this 'storing in Map' is:
> "using which key?"
>
> Maybe you should elaborate on your use case a bit. (Sorry, I
> still have to check up on your recent wiki page and accompanied
> zip.  In any case an upfront thx for sharing that!)
>
> > but in this case the contacts are not displayed (one empty
> contact instead
> > of 4), and submit gives an insert error for "contacts[1]).
> > I had an almost identical problem with JXForms
> > When I skip the Woody form in my flowscript, and just show the
> result page
> > (form2_jx.xml), all my contacts are displayed OK. So JXPath knows how to
> > iterate over a Map.
>
> Could you show how your bean looks like?
> And what is in it?
>
> > I dived into the Woody sources and an obvious place to look is the Java
> > class "RepeaterJXPathBinding.java" and especially the line
> >         Iterator rowPointers =
> > repeaterContext.iteratePointers(this.rowPath);
>
> yep.
>
> > in the function "loadFormFromModel" in this class.
>
> this is for the binding from the bean to the form
>
> as explained above the trouble I see is with binding back from
> the form to the bean (which key to use?)
>
> > Can someone tell me whether this function iteratePointers() gives me the
> > expected result: an iterator over the Map (this.rowPath)? I did
> check the
> > JXPath docs and tried Google. I guess the answer is no, and because the
> > iterator seems to have one value, I guess it returns one object
> with a list
> > of keys and a list of values.
> >
>
> I'm not completely sure what your trying to say here (or do in
> general) but there is afaik a difference in how jxpath looks to
> lists versus maps
>
> LISTS
> suppose myBean.getAddress returns a List then actually jxpath
> looks at your bean as if it would be an XML structure looking like
> <myBean>
>    <address><street/><city/></address>
>    <address><street/><city/></address>
>    <address><street/><city/></address>
> </myBean>
>
> leaving you with expressions like
> $myBean/address[1]/street --> the street of the first address in
> the list, something equivalent to
> ((Address)myBean.getAddress.get(0)).getStreet()
>
> while $myBean/address --> iteration of the 3 address nodes
>
>
> MAPS
> suppose myBean.getAddress returns a Map with 3 keys say "hugo",
> "marc" and "bruno" then actually jxpath looks at your bean as if
> it would be an XML structure looking like
> <myBean>
>    <address>
>      <hugo><street/><city/></hugo>
>      <marc><street/><city/></marc>
>      <bruno><street/><city/></bruno>
>    </address>
> </myBean>
>
> leaving you with expressions like
> $myBean/address[1]/street --> returning nothing
> $myBean/address/hugo/street --> returning the street of the first
> address, ie equivalent to
> ((Address)myBean.getAddress.get("hugo")).getStreet()
>
> and I'm not sure but probably
> $myBean/* --> would give you the iteration of the 3 address nodes
>
>
> in any case, I see some mismatches that would make the current
> RepaterBinding implementation not suitable for these Maps (since
> they are quite directed to the Lists, using the [index] notation
> and all)
>
> however, if you can explain what sort of binding you would expect
> to be happening (in both bean and XML worlds) we can easily go
> for an extra MapRepeater binding or something...
>
> regards,
> -marc=
> PS: a bit swamped, will do a best effort to follow up though
> --
> Marc Portier                            http://outerthought.org/
> Outerthought - Open Source, Java & XML Competence Support Center
> Read my weblog at              http://radio.weblogs.com/0116284/
> mpo@outerthought.org                              mpo@apache.org
>
>



Re: Woody, maps, and repeaters

Posted by Marc Portier <mp...@outerthought.org>.

Hugo Burm wrote:
> 
> I am trying to use the Woody sample that uses a Java bean for its binding
> (form2bean.flow).
> I want to store the contacts in this example in a map instead of in a list,

hm, the biggest problem I see with this 'storing in Map' is: 
"using which key?"

Maybe you should elaborate on your use case a bit. (Sorry, I 
still have to check up on your recent wiki page and accompanied 
zip.  In any case an upfront thx for sharing that!)

> but in this case the contacts are not displayed (one empty contact instead
> of 4), and submit gives an insert error for "contacts[1]).
> I had an almost identical problem with JXForms
> When I skip the Woody form in my flowscript, and just show the result page
> (form2_jx.xml), all my contacts are displayed OK. So JXPath knows how to
> iterate over a Map.

Could you show how your bean looks like?
And what is in it?

> I dived into the Woody sources and an obvious place to look is the Java
> class "RepeaterJXPathBinding.java" and especially the line
>         Iterator rowPointers =
> repeaterContext.iteratePointers(this.rowPath);

yep.

> in the function "loadFormFromModel" in this class.

this is for the binding from the bean to the form

as explained above the trouble I see is with binding back from 
the form to the bean (which key to use?)

> Can someone tell me whether this function iteratePointers() gives me the
> expected result: an iterator over the Map (this.rowPath)? I did check the
> JXPath docs and tried Google. I guess the answer is no, and because the
> iterator seems to have one value, I guess it returns one object with a list
> of keys and a list of values.
> 

I'm not completely sure what your trying to say here (or do in 
general) but there is afaik a difference in how jxpath looks to 
lists versus maps

LISTS
suppose myBean.getAddress returns a List then actually jxpath 
looks at your bean as if it would be an XML structure looking like
<myBean>
   <address><street/><city/></address>
   <address><street/><city/></address>
   <address><street/><city/></address>
</myBean>

leaving you with expressions like
$myBean/address[1]/street --> the street of the first address in 
the list, something equivalent to 
((Address)myBean.getAddress.get(0)).getStreet()

while $myBean/address --> iteration of the 3 address nodes


MAPS
suppose myBean.getAddress returns a Map with 3 keys say "hugo", 
"marc" and "bruno" then actually jxpath looks at your bean as if 
it would be an XML structure looking like
<myBean>
   <address>
     <hugo><street/><city/></hugo>
     <marc><street/><city/></marc>
     <bruno><street/><city/></bruno>
   </address>
</myBean>

leaving you with expressions like
$myBean/address[1]/street --> returning nothing
$myBean/address/hugo/street --> returning the street of the first 
address, ie equivalent to
((Address)myBean.getAddress.get("hugo")).getStreet()

and I'm not sure but probably
$myBean/* --> would give you the iteration of the 3 address nodes


in any case, I see some mismatches that would make the current 
RepaterBinding implementation not suitable for these Maps (since 
they are quite directed to the Lists, using the [index] notation 
and all)

however, if you can explain what sort of binding you would expect 
to be happening (in both bean and XML worlds) we can easily go 
for an extra MapRepeater binding or something...

regards,
-marc=
PS: a bit swamped, will do a best effort to follow up though
-- 
Marc Portier                            http://outerthought.org/
Outerthought - Open Source, Java & XML Competence Support Center
Read my weblog at              http://radio.weblogs.com/0116284/
mpo@outerthought.org                              mpo@apache.org