cocoon-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "Hugo Burm" <hu...@xs4all.nl>
Subject RE: Woody, maps, and repeaters
Date Thu, 21 Aug 2003 17:18:16 GMT
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
>
>



Mime
View raw message