OGNL Indexed and Object Indexed Properties

Hi,

I'm wondering why this code is not working. I'm using struts 2.3.16.1 and
ognl 3.0.6.

In my action class I have this

public String[] getFieldArray() {
System.out.println(">> getFieldArray()");
return null;
}

public void setFieldArray(String[] array) {
}

public MyList<String> getFieldList() {
System.out.println(">> getFieldList()");
return new MyList<String>();
}

public void setFieldList(MyList<String> list) {
}

public MyMap<String, String> getFieldMap() {
System.out.println(">> getFieldMap()");
return new MyMap<String, String>();
}

public void setFieldMap(MyMap<String, String> map) {

}

public String getFieldWithIndex(int index) {
System.out.println(">> getFieldWithIndex(" + index + ")");
return null;
}

public void setFieldWithIndex(int index, String value) {
System.out.println(">> setFieldWithIndex(" + index + "," + value + ")");
}

public String getFieldWithKey(String key) {
System.out.println(">> getFieldWithKey(" + key + ")");
return null;
}

public void setFieldWithKey(String key, String value) {
System.out.println(">> setFieldWithKey(" + key + "," + value + ")");
}

Note that MyList and MyMap are as follows

class MyMap<K, V> implements Map<K, V> { ... }
class MyList<V> implements List<V> { ... }

I have the get() methods overridden on the those classes

On my jsp I have this

<s:property value="fieldArray[1]"/>
<s:property value="fieldList[1]"/>
<s:property value="fieldMap['1']"/>
<s:property value="fieldWithIndex[1]"/>
<s:property value="fieldWithKey['1']"/>

Result is

>> getFieldArray()
>> getFieldList()
MyList.get(1)
>> getFieldMap()
MyMap.get(1)
MyMap.get(1)

Question:
According to OGNL (
http://commons.apache.org/proper/commons-ognl/language-guide.html) under
heading JavaBeans Indexed Properties and OGNL Object Indexed Properties,
getFieldWithIndex(int index) should be called, but it isn't, same goes with
 getFieldWithKey(String key), why ?
I looked at the latest OGNL source code (not the one I'm using since I
couldn't find the source code for version 3.0.6) hoping if I could spot a
method where it tries different get/set methods.
Tried setting breakpoints at OGNLRuntime, ObjectPropertyAccessor but
coulnd't see anything obvious.

At the moment I have a few workarounds
1. Use the ones that are working, i.e. getFieldList() and getFieldMap(),
implementing my own List and Map

2. Use java.util.List getList() and setList(java.util.List list), struts
will create a new List and populate accordingly in the order in which they
were submitted in the form
The issue with this is, if I have a pair or triplet of things that go hand
in hand, then it gets complex.
e.g.
name and address where address is optional
in the form the user put name1, address1, name2 (with no address), and
name3, address3
struts calls setName() with List containing name1, name2, name3
it also calls setAddress() with List containing address1, address3
There is no way the code can then figure out that that address3 is actually
associated with name3
In the past I was able to get around this by supplying another data
structure that tells the code which address belongs to which name but it
involves JavaScript, and it gets messy quite quickly.

3. "Bypass" struts, in the "get" phase (showing the form) just use straight
html combined with struts tags, during the "set" phase (submitting the
form), will just get the parameters using HttpServletRequest
e.g. during show form
<input type="text" name="whateverName" value="<s:property
value="whateverValue"/>"/>
instead of
<s:textfield ... />

Reply via email to