4 Replies Latest reply on Jul 1, 2009 2:48 PM by marcelomagno

    Dinamic List

    marcelomagno

      Hi,


      I Was triying to implement some dinamic behavior to the list pages of my application, following what is sugested in this post:
      http://seamframework.org/Documentation/SeamDynamicCRUD


      Everything worket fine for displaying values in the view, but when I try to update I get this error:


      20:54:08,850 ERROR [STDERR] 29/06/2009 20:54:08 javax.faces.component.UIInput updateModel
      SEVERE: /layout/templateList.xhtml @85,113 value="#{e:evalEl(e:concat(entityList, '.', _templateListSearchFieldList.fieldValue))}": Illegal Syntax for Set Operation



      I am using this custom facelet el function in order to apply values (sugested in this post: http://seamframework.org/Documentation/SeamDynamicCRUD):


           public static Object evalEl(String expression) {
                String framedExpr = "#{" + expression + "}";
                Object value = Expressions.instance().createValueExpression(framedExpr).getValue();
                return value;
           }



      Searching in Google about the Illegal Syntax for Set Operation error I got this:
      http://java.sun.com/javaee/javaserverfaces/1.2/docs/api/javax/faces/component/UIComponent.html#setValueExpression(java.lang.String, javax.el.ValueExpression)


      Set the ValueExpression used to calculate the value for the specified attribute or property name, if any.


      The implementation must call Expression.isLiteralText() on the argument expression. If isLiteralText() returns true, invoke ValueExpression.getValue(javax.el.ELContext) on the argument expression and pass the result as the value parameter in a call to this.getAttributes().put(name, value) where name is the argument name. If an exception is thrown as a result of calling ValueExpression.getValue(javax.el.ELContext), wrap it in a FacesException and re-throw it. If isLiteralText() returns false, simply store the un-evaluated expression argument in the collection of ValueExpressions under the key given by the argument name.



      Is there any workarroud ?


      I am using seam 2.1.1 GA


      Thanks for you help,


      Best Regards,

        • 1. Re: Dinamic List
          niox.nikospara.yahoo.com

          Hello,


          Indeed you are using the EL the wrong way. The function evalEl() returns an Object, which is OK for getting values, but the EL implementation doesn't know how to set its value (in short it returns an rvalue).


          Although I don't know exactly what entityList is, I suggest using it as:


          <h:inputText value="#{entityList[_templateListSearchFieldList.fieldValue]}" />
          



          This requires _templateListSearchFieldList.fieldValue to be String and name a property of the actual entityList (e.g. if _templateListSearchFieldList.fieldValue resolves to "name", entityList should have getName() and setName()), or entityList to be a Map with keys of the same type as _templateListSearchFieldList.fieldValue.


          In any case, I believe that the desired behaviour can be accomplished using maps and EL indirect property references (the bean[propname]).

          • 2. Re: Dinamic List
            marcelomagno

            Hi Nikos, Thanks for your time in replying my post.


            Could you please elaborate a little bit more on the El indirect property references or send me some links or manual references that I could read by myself ?


            Let me try to explain my example a little bit furder, in order for you to understand what the above variable names means in my code. They are all from a seamgen based entityQuery aproach, whith a PojoList.xhtml and a EntityList class as the backend controler. What I am trying to do is to make just one list page for all my entities. So the meanings are:


            entityList -> String holding the name of the my EntityQuery, for this case: eventList
            _templateListSearchFieldList.fieldValue -> String value containing the Entitiquery model object name, and a propertie for this model object, in this case: event.locator


            This is what I have acomplished, based on you explanation
            (please note that I have splited the above _templateListSearchFieldList.fieldValue in two separate String values, meaning:


            _templateListSearchFieldList.listVarValue -> event
            _templateListSearchFieldList.fieldValue -> locator


            1) #{eventList['event'].locator} -> This works


            2) #{e:evalEl(entityList)['event'].locator} -> This works


            3) #{e:evalEl(entityList)['event']._templateListSearchFieldList.fieldName} -> Dont work -> It does not find _templateListSearchFieldList on eventList (what is correct, because event is our eventList varible)


            4) #{e:evalEl(entityList)[e:evalEl(_templateListSearchFieldList.listVarValue)].locator}


            14:29:38,559 WARN  [ExceptionFilter] exception root cause
            javax.el.PropertyNotFoundException: /layout/templateList.xhtml @89,134 value="#{e:evalEl(entityList)[e:evalEl(_templateListSearchFieldList.listVarValue)].locator}": Target Unreachable, 'null' returned null on 'br.com.arquitetodigital.ems.EventList_$$_javassist_3'
            



            5) #{e:evalEl(entityList)['e:evalEl(_templateListSearchFieldList.listVarValue)'].locator


            at java.lang.Thread.run(Unknown Source)
            Caused by: javax.el.PropertyNotFoundException: /layout/templateList.xhtml @90,136 value="#{e:evalEl(entityList)['e:evalEl(_templateListSearchFieldList.listVarValue)'].locator}": Property 'e:evalEl(_templateListSearchFieldList.listVarValue)' not found on type br.com.arquitetodigital.ems.EventList_$$_javassist_3
            




            Unfortunately, I am thinking that this aproach will not succed, because I cannot slice the three parts that I need in order to accomplish the pattern bellow in a working el function for the value parameter of the <h:inputText>



            #{dynamic_entityQuery_name['dynamic_entityQuery_pojo_property_name'].dynamic_pojoProperty_name}


            Could you explain what is the best direction to take? I am very close to what I need, its only missing this set in the restrictions objects.


            Thanks in advance,


            • 3. Re: Dinamic List
              niox.nikospara.yahoo.com

              Hi,


              By indirect references I simply mean the bean[propertyName] syntax. (What is the exact formal name for it?)


              If I get your problem right, it is how to make all the components of an expression like #{a.b.c} dynamic. For the n-1 last parts, you need variables to hold the names, e.g.: if middle="b", tail="c", the following expression is equivalent to the first: #{a[middle][tail]}.


              For the first part I suggest you use Facelets templating. Say you have a page with:


              <ui:include src="/generic/list.xhtml">
                   <ui:param name="first" value="#{a}" />
              </ui:include>
              



              Then in /generic/list.xhtml you can write #{first[middle][last]} and this is translated to #{a.b.c}. So you will have to create a small XHTML for each case, but the bulk of the code is located in a central file, the /generic/list.xhtml.


              In order to dynamically reference the first part, using your evalEL function, #{e:evalEl(entityList)[middle][last]}, is probably OK too, though it may prove less performant.

              • 4. Re: Dinamic List
                marcelomagno

                Hi Nikos. That worked like a charm !!!!


                Thanks a lot for your time and patience !


                The final working statement is:


                <h:inputText value="#{e:evalEl(entityList)[_templateListSearchFieldList.listVarValue][_templateListSearchFieldList.fieldValue]}" />