passing parameters in expression language

1,834 views
Skip to first unread message

Brian Huff

unread,
Dec 4, 2012, 2:54:50 PM12/4/12
to adf-met...@googlegroups.com

Yes, I know it's impossible, and there are workarounds:

https://blogs.oracle.com/jdevotnharvest/entry/passing_parameters_to_managed_bean_method_using_el

But I have an odd use case which makes me wonder about which workaround is correct... I have a semi-complex security model with about 100 states. I'd like to show/hide different buttons based on these states. Some of them can be derived from the binding layer, but some of them are dependent on which action button you're looking at (copy, void, cancel, etc.). Some are globally enabled (for superusers), some are enabled only if the user is the creator of the object you're looking at.

So, I could create a property listener to set the "actionName" in the viewScope, and have a backing bean with a generic "isAllowed" function... pull the values from the bindings, and return a boolean yes/no. But if I'm making this call 100 times on every page, is there any chance that they would be done out of order??? Is 'viewScope' the correct scope for this, or is something better? I could also make a bean with 100 boolean values so I can grab them with expression language... but that just makes me sad.

The back end model is secured (web services) so I'm not worried about security holes... this is purely a UI consideration. So a 99% solution would be fine.

--

Brian 'Bex' Huff
Chief Software Architect
Bezzotech - THE Premier Oracle ECM Solution Provider
Email: b...@bezzotech.com
Mobile: +1.612.227.6057

Designing a Content Management or Enterprise 2.0 strategy? This may help:
 http://bezzotech.com/library.html

Brian Huff

unread,
Dec 4, 2012, 6:05:05 PM12/4/12
to adf-met...@googlegroups.com

That's a really good idea! I'm most of the way through implementing that. I'll share my source code on a blog post when I'm done. Anybody else frustrated by this limitation? Is there logic behind it? Force developers to use bindings for all their data access?

The only drawback is that ADF wont compile an ADF page with parenthesis in them, so I have to use a special character to denote calling a function. I'm using double underscore:

${myBean.foo__bar}

Thanks!

On Tue, Dec 4, 2012 at 1:08 PM, Jakub Pawłowski <kubapaw...@gmail.com> wrote:
Hi,

I'd recomend to write custom JSF ELResolver class to have a central place of components control. E.g. #{isAllowed('expression')}. You may pass component ID and e.g. actionName to check is it accessible.

Kuba

--
You received this message because you are subscribed to the ADF Enterprise Methodology Group (http://groups.google.com/group/adf-methodology). To unsubscribe send email to adf-methodolo...@googlegroups.com
 
All content to the ADF EMG lies under the Creative Commons Attribution 3.0 Unported License (http://creativecommons.org/licenses/by/3.0/). Any content sourced must be attributed back to the ADF EMG with a link to the Google Group (http://groups.google.com/group/adf-methodology).

Simon Lessard

unread,
Dec 4, 2012, 6:37:00 PM12/4/12
to adf-met...@googlegroups.com
Hi Brian,

What version of ADF are you using? This is an important question as Servlet 3.0 and, more importantly, EL 2.2 introduced method calls. Another option, which could be more interesting in your case, assuming you're using JSF 2.0, would be to leverage the component attribute with the new getCurrentComponent method (http://docs.oracle.com/javaee/6/api/javax/faces/component/UIComponent.html#getCurrentComponent(javax.faces.context.FacesContext))  in the ELResolver to get the current component, extract its attributes to get the parameters and then execute the logic.

Another option (beside the resolver) would be to implement a custom ValueExpression and define it by default for the rendered attribute by creating an Application decorate overriding the various create component method. The expression implementation would check if the attributes is present, if so apply the logic, else return true. The main advantage would be that you would no longer have to specify the rendered attribute in the page, only the <f:attribute>. There would be a huge drawback though though as that value would be overridden if the rendered attribute was to be specified on the tag. Depending on your exact use cases that may or not be an issue.

Yet another way depending on JSF 2.0 would be to use system event to hook some logic on the components. Putting it simply, JSF 2.0 offers you way more option to achieve what you're trying to do. If you have only JSF 1.2, I would advise a #{bean.invokeMethod[methodName][parameter1][parameter2]...[parameterN]} syntax. It more complex to implement, but it's also way more flexible and easier to read IMHO. Furthermore, since it's a recognized syntax, the compiler won't whine and new developers will get used to it faster. To implement such syntax you must create a resolver that:

- handles the tuple base=?, property="invokeMethod" and in which case it should return an internal MethodInvoker instance (inner static class)
- handles the tuple base=MethodInvoker instance, property=?, which either return a modified MethodInvoker instance (or a new one) that include the parameter, or the method's invocation result if all parameters were already specified. This option does not allow method overload though.

Another syntax is #{bean.invokeMethod[methodName][parameterCount][parameter1][parameter2]...[parameterN]} which uses a resolver with pretty much the same logic, but that support method overload at the cost of another EL element. I implemented that last one in a project using JSF 1.2 and it works quite nicely. Of course, if you only have one method you want to make available and not something generic, defining a specialized ELResolver is perfectly acceptable and even more efficient since it has less processing to do.


Regards,

~ Simon
Simon LessardADF Architect
CMA SYSTeMS

Brian Huff

unread,
Dec 4, 2012, 7:32:02 PM12/4/12
to adf-met...@googlegroups.com

Sorry, should have mentioned version: ADF 11.1.1.6, which I believe is just JSF 1.2... I tried the following syntax:

${bean.foo('bar')}
${bean.foo['bar']}
#{bean.foo('bar')}
#{bean.foo['bar']}

All either give syntax errors or javax.el.PropertyNotFoundException.

I like your 'invoke' syntax.... Might switch to that now that I got it working. I did have to hack the 'getType' function to always return a 'String' object as the type... so this might be tricky to use when the return field is a number or a date, but Strings are easy to convert.

Amr Gawish

unread,
Dec 4, 2012, 7:37:06 PM12/4/12
to adf-met...@googlegroups.com
Hi Brian,
If you have only one parameter there is a cool way I use to give my EL a parameter, which is implementing a Map interface

When you do, you get a get method which takes an object parameter, you can anticipate this parameter and return the output the way you like

and you can access this easily in your EL using #{bean['bar']}

Best Regards,
Amr Gawish

Brian Huff

unread,
Dec 4, 2012, 10:58:58 PM12/4/12
to adf-met...@googlegroups.com

Unfortunately I can't do that :-(

In order to do the security check, I need logic that depends on 3 variables in the binding layer.

shanth...@gmail.com

unread,
Dec 5, 2012, 12:54:13 AM12/5/12
to adf-met...@googlegroups.com
Jboss EL has an implementation that allows methods to be called in el, not sure if it would compatible with adf faces, though have used it with a lot of other jsf implementations.

Thanks
Sk
Sent from BlackBerry® on Airtel

From: Jakub Pawłowski <kubapaw...@gmail.com>
Date: Tue, 4 Dec 2012 13:08:10 -0800 (PST)
Subject: [ADF EMG] Re: passing parameters in expression language

Hi,

I'd recomend to write custom JSF ELResolver class to have a central place of components control. E.g. #{isAllowed('expression')}. You may pass component ID and e.g. actionName to check is it accessible.

Kuba



W dniu wtorek, 4 grudnia 2012 20:54:50 UTC+1 użytkownik bex napisał:

Jean-Marc Desvaux

unread,
Dec 5, 2012, 3:59:45 AM12/5/12
to adf-met...@googlegroups.com
Brian,

I understand the security decision is based on predefined values of the 3 variables.
What about using a custom EL with one string parameter which would represent a list of the the required values for each 3 variables "hardcoded" with separators convention.
As an example:
v1,v2,v3 are the variables which can have many possible values to allow the action. 
If Button "Save" must be rendered only if v1 = 1 or 2 ; v2 = 3 and v3 = 4 or 5 or 6.
String could be 'v1:1,2;v2:3;v3:4,5,6'
The session bean method implemented will pass the string and check against the active values.

Not sure if it can help but you can check slides 45 to 47 at http://jmdesvaux.blogspot.com/2010/11/migrate-and-integrate-forms-reports-and.html 
Our security variables values (privileges codes) are selected from the db, then set in AM session and into an HTTP session map, then compared in the security custom methods with the string parameter of the custom EL method.

JM

Simon Lessard

unread,
Dec 5, 2012, 4:03:27 AM12/5/12
to adf-met...@googlegroups.com
Hi Brian,

Yes, that's because there's no resolver for foo property on the bean object for the case 2 and 4 and there's a pure syntax  error with versions 1 and 3 prior to EL 2.2. I don't really get why you had to hack the getType though, at worst just return Object.class. Also note that the [] syntax gives another 2 huge advantages over the __, the parsing won't have to be done by you, and it will support EL nesting. For example, the following would be valid:

#{bean1.invoke['foo'][2][bindings.AttrBinding.value][bean2.someAttr]}

As for the Map option, it's indeed nice for one parameter, but it remains a bit weird to implement and quite not what a Map should be used for.


Regards,

~ Simon

Jan Vervecken

unread,
Dec 6, 2012, 4:05:56 PM12/6/12
to adf-met...@googlegroups.com
hi Brian 'Bex' Huff

It might be possible for the Map implementation approach to support your multiple parameters EL requirement.

You could review the sample code available via the OTN forum message
at https://forums.oracle.com/forums/message.jspa?messageID=10046152#10046152
where the idea is to build a String with the EL expression you need, using an EL expression, and then evaluate it.

Your use-case is different, but if you alter the sample to hold on to the different "keys" (e.g. in a list), instead of concatenating them as String, it might allow you to use them as parameters for the method call you need to make.

success
Jan Vervecken
Reply all
Reply to author
Forward
0 new messages