1

There is an object (ObjectA) which has another object inside (ObjectB). There is a Guava TreeBasedTable inside the Object B. This Table has a string as row-key,column-key and another object "ObjectC" as value. This table has been displayed on the jsp using the <s:iterator/> and <s:textfield/> tags and it is being displayed correctly (the "values" inside the <s:textfield/> are correct but the "names" are not).

Now, the problem arises when the <s:textfield/> is modified. How do we capture the modified values inside ObjectC in the action class?

public class ObjectA implements Serializable {
private Integer attr1;
private List<ObjectB> objB;
//...getters and setters....
public class ObjectB implements Serializable {
private Integer attr11;
private Table<String,String,ObjectC> allPFields;
// ...getters and setters....
public class ObjectC implements Serializable {
private Integer attr111;
public String attr112;
// ...getters and setters....

jsp code:

<!-- language: lang-html -->

<s:iterator value="#objB.allPlainFields.row(#rowKey)" var="fieldMap"
    status="fieldStatus">
    <li><label><s:property value="#fieldMap.key" /></label><span>
            <s:textfield name="<NOT SURE>" value="%{#fieldMap.value.attr12}" />
    </span></li>
</s:iterator>

A TreeBasedTable in Guava is similar to a map inside a map, I tried doing allPFields[#outerkey][#innerkey].attr112 but, it didn't work.

The object structure when the screen is displayed with existing values in the database

<!-- language: lang-java -->
objA        
objBList    ArrayList<E>  (id=668)  
elementData Object[10]  (id=7438)   
    [0] objB  (id=7439) 
        allPFields  TreeBasedTable<R,C,V>  (id=7443)    
            backingMap  TreeMap<K,V>  (id=8116) 
            cellSet null    
            columnComparator    NaturalOrdering  (id=503)   
            columnKeySet    null    
            columnMap   null    
            factory TreeBasedTable$Factory<C,V>  (id=8117)  
            rowKeySet   null    
            rowKeySet   StandardRowSortedTable$RowKeySortedSet  (id=8118)   
            rowMap  StandardRowSortedTable$RowSortedMap  (id=8119)  
            rowMap  null    
            values  null

And the "allPFields" looks like the following in action:

{OuterKey1=
    {InnerKey1=ObjectC[attr111=31, attr112=Hi there], 
     InnerKey2=ObjectC[attr111=40, attr112=How are you]
    }
 }

The "allPFields" value above has been picked up from the IDE console.

Vickym
  • 137
  • 2
  • 10

1 Answers1

0

As I told you in your other question, I've never used Guava TreeBasedTable;

However, according to the Official Guava Documentation, a

TreeBasedTable , which is essentially backed by a TreeMap<R, TreeMap<C, V>>

and the get method is

V get(Object rowKey, Object columnKey)

Returns the value corresponding to the given row and column keys, or null if no such mapping exists.

In Java it would be:

Object value = objA.getObjB().get(listIndex).getAllPlainFields.get(rowKey, columnKey).getAttr112;
value = "new value";

Then in OGNL you could try something (totally untested) like:

<s:textfield value="%{#fieldMap.value.attr12}"
 name="objA.objB[#fieldStatus.index].allPlainFields.get(#rowKey, #fieldMap.Key).attr112"  />

P.S: BEWARE OF TYPO... you are using allPlainFields and allPFields together... one of them is wrong, make sure that all the notations point to the right variable name.

P.P.S: I don't know your requirements, but this structure seems a little "over-designed" to me... it definitely does not respect the KISS paradigm :)

Community
  • 1
  • 1
Andrea Ligios
  • 49,480
  • 26
  • 114
  • 243
  • Tried this but didn't work: ` ` ....somehow, I have not been able to make methods work using OGNL. The moment I use a method, the object (ObjB) is sent as null. – Vickym Feb 20 '13 at 11:16
  • Ahh... have you disabled `Dynamic Method Invocation` in Struts.xml (if yes, re-enable it)? Have you verified if the getter in `ObjectB` is `getAllPFields` or `getAllPlainFields` ? – Andrea Ligios Feb 20 '13 at 11:22
  • Yes, `Dynamic Method Invocation` was set to false..I have enabled it...let me check now. – Vickym Feb 20 '13 at 11:33
  • Still objB is null in the action...the `` is rendered as ``....Tried it with `row(rowkey)[columnkey]` as well. – Vickym Feb 20 '13 at 11:49
  • The following code brings a nonNull `objB` in action but the `allPlainfields` is still `NULL`. The code: `objA.objB[%{#fieldStatus.index}].allPlainFields['%{rowKey}']['%{#fieldMap.key}'].attr112`.....any further clues? I understand about your complexity statement...We need to display a table on the screen (Map,Map)and hence the choice.... – Vickym Feb 20 '13 at 12:19
  • it is allPlainFields. sorry missed it. – Vickym Feb 20 '13 at 13:00
  • another interesting thing. If I define a `textfield` as follows, the value is correctly displayed. That means, the `value` attribute takes method but the `name` doesn't. `` – Vickym Feb 20 '13 at 13:19
  • moving ahead: the following code in the iterator does display correct value but when the value is modified and submitted, the objB in `action` is still null. Please note that, the `value` attribute has not been mentioned for the `textfield`. That means, the `name` attribute is sufficient to display the `value`. `` – Vickym Feb 20 '13 at 13:42
  • Do you have default (no args) constructors in your Objects ? I mean, explicit definition OR no other consctructors definition ? Maybe something is preventing the object to be correctly instantiated by OGNL... – Andrea Ligios Feb 20 '13 at 13:57
  • `ObjectA`, `ObjectB` and `ObjectC` have `no args constructor`. However, the `TreeBasedTable` has to be created using `TreeBasedTable.create()`. Could this be an issue? – Vickym Feb 20 '13 at 14:04
  • Absolutely yes. But I'm conducting some experiments using `TreeMap>` and it is not working the same. I'm afraid the problem is in the double casting... stay tuned. – Andrea Ligios Feb 20 '13 at 14:43
  • Currently looking at issues at apache jira: [link]https://issues.apache.org/jira/browse/WW-3866 [link]https://issues.apache.org/jira/browse/OGNL-221 – Vickym Feb 20 '13 at 16:35
  • Nice... I'm currently using that version (2.3.1.2), affected by the problem, and tried with a TreeMap, as in the Jira. Try upgrading S2 (for test purposes) and using nested Treemap instead of Guava stuff, that adds the problem of the .create() method... let us know – Andrea Ligios Feb 20 '13 at 16:49
  • Tried with a TreeMap> but facing an issue. [http://stackoverflow.com/q/15006868/2087216] – Vickym Feb 21 '13 at 16:09