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:[EMAIL PROTECTED]
Sent: Thursday, August 21, 2003 12:33 PM
To: [EMAIL PROTECTED]
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/
[EMAIL PROTECTED]                              [EMAIL PROTECTED]






-- Marc Portier http://outerthought.org/ Outerthought - Open Source, Java & XML Competence Support Center Read my weblog at http://radio.weblogs.com/0116284/ [EMAIL PROTECTED] [EMAIL PROTECTED]



Reply via email to