Re: EL expressions as custom component attributes

2013-03-07 Thread l.pe...@senat.fr

On 06/03/2013 20:02, Leonardo Uribe wrote:

Hi

There are good reasons to avoid use VariableMapper. This class is used
when the EL expressions are built to store some values required to
resolve the expression later, making the expression not cacheable,
because the content of VariableMapper could change at any time and in
that way, it is not possible to reuse the same expression.

The wrappers used for EL expressions are there to ensure proper
context initialization. For example, when the EL expression is
evaluated, the reference for the composite component must be pushed on
to the stack.

This process is done by facelets, so create a value expression like
#{cc} programatically will not have the same effect as if it is
created by facelets compiler (if it is located inside composite
component .xhtml file).

If you need some kind of global context in your pages, the best way is
write a custom EL resolver. Other option is write an specific facelets
function, and pass the reference to the composite component to
retrieve the specified context and finally resolve it properly. For
example:

#{utils:context(cc).selected.attribute1}

Really I don't know what you are trying to do, but I hope these ideas
could help.

Thank you for this reply.

My application manages collections of tens of types.

It is some kind of CRUD + collections management.

As I do not like to copy paste code over and over, I wrote a lib that 
analyses those types
to decide how they should be displayed or edited. It uses custom 
annotations and information
provided by hibernate (all those type are hibernate objects). I call 
this information a mapping.


For collections that should be displayed as a datatable, I use this 
mapping to dynamically instantiate columns

So, I have code like :

 p:dataTable ... var=elutit
c:forEach items=#{mapper.mappings} var=curProp
my:displayColumn mapper=#{mapper} bean=elutit
mappingDesc=#{curProp}/
/c:forEach
/p:dataTable

my:displayColumn is a custom class extending Column that will use the 
mapping and the bean to correctly display a property as a column.
To ensure dynamic update, the values and parameters of the display 
controls added as children of this custom column are set as 
ValueExpression-s.


In this datatable example I have no problem, as the bean name (here 
elutit) is local to the control. Value expression will be for example 
#{elutit.property1}


For generic editions, I have controls that derives from layouting 
controls such as panels. As I like PrimeFaces, I most often use a 
control derivating from PanelGrid. This control takes various parameters 
as attributes : the mapper, the bean, etc. Similar to the dataTable, it 
adds edition controls as children, setting their values with 
ValueExpression-s.



The bean to display is specified as an attribute of this custom control, 
with an EL expression : #{myBean}.
I need to get a hand on an EL expression that can reference myBean in 
the ValueExpressions I generate for display controls.
I use this EL Expression as a parameter of my generated ValueExpressions 
In some cases, a property value will not be just #{myBean.property1} but 
#{my:customFunction(myBean)}, with #{my:customFunction(inst)} 
specified in mapping configuration and inst replaced by the right EL 
expression.


Following your advice, I took a look at custom EL resolvers. It is 
definitely a good solution for mapping absolute names.
I did not see how it can help me in my case of a custom control used 
inside a tag file.


In this case, you can have the top level variable A specified as 
parameter B to the tag component, using it as parameter C of the custom 
component.
I need a way to get track of these successive mappings. Ideally, I would 
be able to instantiate my ValueExpressions with the exact same context, 
and so the same variable mappings.



Thanks again for your attention, I hope my English makes sense...

Best regards,

Ludovic
|
| AVANT D'IMPRIMER, PENSEZ A L'ENVIRONNEMENT.
|



Re: EL expressions as custom component attributes

2013-03-06 Thread l.pe...@senat.fr

Well,

reading my message again, I found that I still does not properly explain 
my problem.


It is not really to pass a bean using an EL expression.

To do that, you just declare getBean/setBean as returning/taking as 
parameter an Object, and that's done.


My custom component generates itself some custom EL.

So, I need to grab the ValueExpression used to pass this bean.

I found that I can do so using getValueExpression(bean) in my custom 
component method.
However, I found no clean way (I mean, other than reflection) to get a 
hand on the wrapper VariableMapper, to perform mappings before reusing 
the expression or to specify to use this mapper when evaluating my 
custom expressions.


In my example, my custom component generated EL expressions such as 
#{context.selected.attribute1} . Without proper VariableMapper, 
evaluation just fails as context is not defined.


Thanks in advance for your patience.

Ludovic
On 06/03/2013 10:22, l.pe...@senat.fr wrote:


I do not succeed in passing EL expressions as attributes of a custom 
component used in a tag file.


I could not find a clear doc on how to do that with EL 2.2.

My use case is the following :

 1. a tag file taking attribute context as a parameter
 2. inside the tag file, using a home made custom component taking
bean as a parameter

Context is an instance of an in-house class hierarchy. Bean is most 
often in this case #{context.selected}.


If I use my tag file the following way in a top level f:view :

|my:tag  context=#{adminContext}/|

And inside my:tag definition :

|my:custom  bean=#{context.selected}/|

In my custom component, I have tried accessors like

|public  ValueExpression  getBean()  {
 return  (ValueExpress
ion)  getStateHelper().eval(PropertyKeys.bean);
}

public  void  setBean
span class=pun style=margin: 0px; padding: 0px; border: 0px; font-size: 14px; 
vertical-align: baseline; background-color: transparent; color: rgb(0, 0, 0); background-position: 
initial initial; background-repeat: initial initial;(ValueExpression  param)  {
 getStateHelper().put(P
ropertyKeys.bean,  param
span class=pun style=margin: 0px; padding: 0px; border: 0px; font-size: 14px; 
vertical-align: baseline; background-color: transparent; color: rgb(0, 0, 0); background-position: 
initial initial; background-repeat: initial initial;);
}|

and attribute declaration of custom component in taglib like :

|attribute
 descriptionNom du bean à afficher/description
 namebean/name
 requiredtrue/required
 deferred-value
 typejava.lang.Object/type
 /deferred-value
/attribute|

and attribute declaration of the tag file like :

|attribute
 namecontext/name
 deferred-value
 typejava.lang.Object/type
 /deferred-value
 requiredtrue/required
/attribute|

I always get a cast to ValueExpression exception when calling getBean().

In a method of the custom component called by encodeBegin, I noticed 
that I can access the attribute using getValueExpression(bean).


It returns an instance of ContextAwareTagValueExpressionUEL. Its 
_wrapped attribute points to an instance of WrappedValueExpression, 
encapsulating a ValueExpressionImpl whose value (expr) is 
#{context.selected}. This instance of ValueExpressionImpl also has a 
VariableMapper handling the translation of context to 
adminContext. Its expected type is javax.el.ValueExpression. This 
must cause my exception...


How can I make it works ?

Thanks in advance.

I am using MyFaces 2.1.9, CODI 1.0.5, OpenWebBeans 1.1.6, Tomcat 7.0.32.

(question also asked on 
http://stackoverflow.com/questions/15229708/el-expressions-as-custom-component-attributes 






|
| AVANT D'IMPRIMER, PENSEZ A L'ENVIRONNEMENT.
|


Re: EL expressions as custom component attributes

2013-03-06 Thread Leonardo Uribe
Hi

There are good reasons to avoid use VariableMapper. This class is used
when the EL expressions are built to store some values required to
resolve the expression later, making the expression not cacheable,
because the content of VariableMapper could change at any time and in
that way, it is not possible to reuse the same expression.

The wrappers used for EL expressions are there to ensure proper
context initialization. For example, when the EL expression is
evaluated, the reference for the composite component must be pushed on
to the stack.

This process is done by facelets, so create a value expression like
#{cc} programatically will not have the same effect as if it is
created by facelets compiler (if it is located inside composite
component .xhtml file).

If you need some kind of global context in your pages, the best way is
write a custom EL resolver. Other option is write an specific facelets
function, and pass the reference to the composite component to
retrieve the specified context and finally resolve it properly. For
example:

#{utils:context(cc).selected.attribute1}

Really I don't know what you are trying to do, but I hope these ideas
could help.

regards,

Leonardo Uribe

2013/3/6 l.pe...@senat.fr l.pe...@senat.fr:
 Well,

 reading my message again, I found that I still does not properly explain my
 problem.

 It is not really to pass a bean using an EL expression.

 To do that, you just declare getBean/setBean as returning/taking as
 parameter an Object, and that's done.

 My custom component generates itself some custom EL.

 So, I need to grab the ValueExpression used to pass this bean.

 I found that I can do so using getValueExpression(bean) in my custom
 component method.
 However, I found no clean way (I mean, other than reflection) to get a hand
 on the wrapper VariableMapper, to perform mappings before reusing the
 expression or to specify to use this mapper when evaluating my custom
 expressions.

 In my example, my custom component generated EL expressions such as
 #{context.selected.attribute1} . Without proper VariableMapper, evaluation
 just fails as context is not defined.

 Thanks in advance for your patience.

 Ludovic

 On 06/03/2013 10:22, l.pe...@senat.fr wrote:


 I do not succeed in passing EL expressions as attributes of a custom
 component used in a tag file.

 I could not find a clear doc on how to do that with EL 2.2.

 My use case is the following :

  1. a tag file taking attribute context as a parameter
  2. inside the tag file, using a home made custom component taking
 bean as a parameter

 Context is an instance of an in-house class hierarchy. Bean is most often
 in this case #{context.selected}.

 If I use my tag file the following way in a top level f:view :

 |my:tag  context=#{adminContext}/|

 And inside my:tag definition :

 |my:custom  bean=#{context.selected}/|

 In my custom component, I have tried accessors like

 |public  ValueExpression  getBean()  {
  return  (ValueExpress
 ion)  getStateHelper().eval(PropertyKeys.bean);
 }

 public  void  setBean
 span class=pun style=margin: 0px; padding: 0px; border: 0px; font-size:
 14px; vertical-align: baseline; background-color: transparent; color: rgb(0,
 0, 0); background-position: initial initial; background-repeat: initial
 initial;(ValueExpression  param)  {
  getStateHelper().put(P
 ropertyKeys.bean,  param
 span class=pun style=margin: 0px; padding: 0px; border: 0px; font-size:
 14px; vertical-align: baseline; background-color: transparent; color: rgb(0,
 0, 0); background-position: initial initial; background-repeat: initial
 initial;);

 }|

 and attribute declaration of custom component in taglib like :

 |attribute
  descriptionNom du bean à afficher/description
  namebean/name
  requiredtrue/required
  deferred-value
  typejava.lang.Object/type
  /deferred-value
 /attribute|

 and attribute declaration of the tag file like :

 |attribute
  namecontext/name
  deferred-value
  typejava.lang.Object/type
  /deferred-value
  requiredtrue/required
 /attribute|

 I always get a cast to ValueExpression exception when calling getBean().

 In a method of the custom component called by encodeBegin, I noticed that
 I can access the attribute using getValueExpression(bean).

 It returns an instance of ContextAwareTagValueExpressionUEL. Its _wrapped
 attribute points to an instance of WrappedValueExpression, encapsulating a
 ValueExpressionImpl whose value (expr) is #{context.selected}. This instance
 of ValueExpressionImpl also has a VariableMapper handling the translation of
 context to adminContext. Its expected type is javax.el.ValueExpression.
 This must cause my exception...

 How can I make it works ?

 Thanks in advance.

 I am using MyFaces 2.1.9, CODI 1.0.5, OpenWebBeans 1.1.6, Tomcat 7.0.32.

 (question also asked on
 http://stackoverflow.com/questions/15229708/el-expressions-as-custom-component-attributes



 |
 | AVANT D'IMPRIMER,