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 jxpathso 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]
