jsf - el function with bean - jsf

Hi i can define functions like this for el:
<function>
<function-name>areAllGranted</function-name>
<function-class>org.springframework.faces.security.FaceletsAuthorizeTagUtils</function-class>
<function-signature>boolean areAllGranted(java.lang.String)</function-signature>
</function>
</facelet-taglib>
but what can i do if i want to use a spring bean with initalised autowired-fields, instead of a plain new instance of an class?

If your're using a Servlet 3.0 container which supports EL 2.2 (Tomcat 7, Glassfish 3, etc), just do it.
<h:someComponent rendered="#{bean.areAllGranted('someString')}">
If your're using an old Servlet 2.5 container which doesn't support it, then install JBoss EL so that you can use the new EL 2.2 syntax. This is answered in detail here: Invoking methods with parameters by EL in JSF 1.2

Related

How to pass parameters into a p:commandbutton? [duplicate]

How can I in JSF 2.0 invoke direct methods or methods with arguments / variables / parameters in EL?
For example, getting the list size in EL:
<h:outputText value="#{bean.list.size()}" />
Or invoking an action method with arguments:
<h:commandButton value="edit" action="#{bean.edit(item)}" />
This does not seem to work in my environment. It doesn't seem to like parentheses.
javax.el.ELException: Error Parsing: #{bean.list.size()}
com.sun.el.parser.ParseException: Encountered "("
In standard EL prior to EL 2.2 from Java EE 6 you cannot directly invoke methods like
#{bean.method()} nor invoke methods with arguments like #{bean.method(arg1, arg2).
If upgrading to a EL 2.2 / Java EE 6 compliant container (Tomcat 7, Glassfish 3, JBoss AS 6, etc) is not an option and you're currently using EL 2.1 / Java EE 5 (Tomcat 6, Glassfish 2, JBoss AS 4, etc), then your best bet is to install JBoss EL. JBoss EL is an EL 2.1 compliant implementation which supports the same features as EL 2.2. Installing JBoss EL is a matter of putting the jboss-el.jar in /WEB-INF/lib and adding the following to the web.xml, assuming that you're using Mojarra:
<context-param>
<param-name>com.sun.faces.expressionFactory</param-name>
<param-value>org.jboss.el.ExpressionFactoryImpl</param-value>
</context-param>
Or, when you're using MyFaces:
<context-param>
<param-name>org.apache.myfaces.EXPRESSION_FACTORY</param-name>
<param-value>org.jboss.el.ExpressionFactoryImpl</param-value>
</context-param>
An alternative for your particular case is to use JSTL's fn:length:
<h:outputText value="#{fn:length(bean.list)}" />
Another alternative is to add a getter to the bean which returns List#size() or in some specific cases a custom EL function.
Please note thus that invoking methods with arguments in EL is not a JSF 2.0 specific feature. It's an EL 2.2 specific feature. EL 2.2 is part of Java EE 6, which JSF 2.0 is also part of. So it look like a JSF 2.0 specific feature, but it isn't. JSF 2.0 is backwards compatible with Servlet 2.5 / EL 2.1 which lacks this feature. On the other hand, JSF 1.x is forwards compatible with Servlet 3.0 / EL 2.2, so it would also be possible to use this feature in JSF 1.x then, also using JBoss EL on Servlet 2.5 / EL 2.1.
BalusC's answer is correct, however, when you use maven, you should exclude el-api 1.0 transitive dependency like this:
<dependency>
<groupId>org.jboss.seam</groupId>
<artifactId>jboss-el</artifactId>
<version>2.0.0.GA</version>
<!-- exclude el-api 1.0 transitive dependency -->
<exclusions>
<exclusion>
<groupId>javax.el</groupId>
<artifactId>el-api</artifactId>
</exclusion>
</exclusions>
</dependency>

Migrating JSF 1.1 with Ajax4jsf 1.x to JSF 2

We are migrating JSF 1.1 (MyFaces) project to JSF 2. The idea is to migrate periodically by keeping both JSP and XHTML together for some time. We use many ajax4jsf-1.1.1 tags in JSP pages. We don't use RichFaces. After configuring the system to JSF 2 (with all config changes mentioned in tutorial by Balusc) When tried to access the JSP page with ajax4jsf.jar in classpath, we get an exception:
Caused by: java.lang.IllegalStateException: setViewHandler may not be executed after a lifecycle request has been completed
at org.apache.myfaces.application.ApplicationImpl.setViewHandler(ApplicationImpl.java:853)
at org.ajax4jsf.framework.ajax.InitPhaseListener.beforePhase(InitPhaseListener.java:92)
at org.apache.myfaces.lifecycle.PhaseListenerManager.informPhaseListenersBefore(PhaseListenerManager.java:76)
at org.apache.myfaces.lifecycle.LifecycleImpl.executePhase(LifecycleImpl.java:131)
It looks ajax4jsf.jar is not compatible with JSF 2. Looks some issue with LifeCycle configuration.
Is there any way we can make a4j work with JSF 2 JSPs? I know when we use XHTML we don't need all this.
Get rid of Ajax4jsf 1.x altogether. It's indeed not compatible with JSF2. Instead, JSF2 offers a new main ajax tag <f:ajax> which covers all the core functionality as previously offered by Ajax4jsf 1.x.
If upgrading to RichFaces 4 is not an option (because, as you said yourself, you aren't using RichFaces components anywhere), then just remove Ajax4jsf 1.x and replace all <a4j:xxx> tags by standard JSF2 equivalents.
<a4j:ajaxListener>: use <f:ajax listener>.
<a4j:keepAlive>: just put managed bean in the view scope by #ViewScoped.
<a4j:log>: use jsf.ajax.addOnEvent() or jsf.ajax.addOnError() in JS context.
<a4j:commandLink>: just nest <f:ajax> inside <h:commandLink>.
<a4j:outputPanel>: use <h:panelGroup> and remember to include its ID in <f:ajax render> or PrimeFaces <p:outputPanel>.
<a4j:repeat>: just use standard <ui:repeat>.
<a4j:form>: just use <h:form>, it will autorecognize <f:ajax>.
<a4j:htmlCommandLink>: just nest <f:ajax> inside <h:commandLink>.
<a4j:jsFunction>: just use standard <h:commandScript>. It was however introduced late in JSF 2.3. If you can't upgrade to JSF 2.3 then consider OmniFaces <o:commandScript> or PrimeFaces <p:remoteCommand>.
<a4j:region>: just use <f:ajax execute>, you can even wrap <f:ajax> around a group of components.
<a4j:loadBundle>: just use standard <f:loadBundle>.
<a4j:status>: use jsf.ajax.addOnEvent() or jsf.ajax.addOnError() in JS context.
<a4j:actionparam>: just use standard <f:param>.
<a4j:loadScript>: just use standard <h:outputScript>.
<a4j:mediaOutput>: no replacement. Consider PrimeFaces <p:media>.
<a4j:poll>: no replacement. Consider OmniFaces <o:commandScript> or PrimeFaces <p:poll>.
<a4j:commandButton>: just nest <f:ajax> inside <h:commandButton>.
<a4j:include>: just use standard <ui:include>.
<a4j:loadStyle>: just use standard <h:outputStylesheet>.
<a4j:support>: just use standard <f:ajax>.
You also need to rename/rewrite JSP files to Facelets files. In simple cases, this is usually just a matter of changing root declarations and file extensions. Facelets makes it easier to replace all duplicated code by a single template. The following answer applies:
Migrating from JSF 1.2 to JSF 2.0

How to pass a method argument to getter?

I want to use a datalist
<rich:dataList value="#{bean.itemsOnLevel}" var="item">
<h:outputText value="#{item.value}" />
</rich:dataList>
but my getter needs a parameter
public List getItemsOnLevel(int level);
how can I pass the level?
If you're already targeting a Servlet 3.0 compatible container (Tomcat 7, Glassfish 3, JBoss 6, etc) with a Servlet 3.0 compatible web.xml in your webapp, then you can make use of the new EL 2.2 feature of invoking methods with arguments:
<rich:dataList value="#{bean.getItemsOnLevel(1)}" var="item">
<h:outputText value="#{item.value}" />
</rich:dataList>
If you're however targeting an older Servlet 2.5 compatible container (Tomcat 6, Glassfish 2, JBoss 4/5, etc), then your best bet is to install JBoss EL to achieve the same. See also this answer for details: Invoke direct methods or methods with arguments / variables / parameters in EL

Passing parameters to a method in h:outputtext tag

I would like to display a text in jsf screen by passing an attribute to a method implemented in backing bean. I have to pass a dynamic value as an attribute. I tried the below but it seems to be an incorrect syntax -
<h:outputText value="#{getValue(#{item.product}).component.address}" />
Apart from the syntax error (you can never nest EL expressions like as #{#{}}), the following is valid in EL 2.2 which is in turn part of Servlet 3.0 / Java EE 6:
<h:outputText value="#{bean.getValue(item.product).component.address}" />
So if you have a Servlet 3.0 compatible target runtime (Tomcat 7, Glassfish 3, JBoss 6, etc) with a Servlet 3.0 compatible web.xml, then you can invoke non-getter methods with arguments like this.
However, based on your question history you're using JSF 1.2 and the chance is big that you're also targeting an older container where the above wouldn't work. If it is a Servlet 2.5 container, then you could use JBoss EL to get this EL syntax to work.
See also:
Invoking methods with parameters by EL in JSF 1.2
JSF 1.2 w/ EL 2.1 (the usual pairing) doesn't support calling methods with parameters on beans using EL expressions.
There exists one hack, abusing the fact that JSF EL expressions work on maps:
value="#{myBean['product']}"
This will assume myBean is implementing Map interface and will call get method with 'product' as parameter. I don't know if the key can be dynamically computed but it's worth a try.
Syntax would be:
value="#{myBean[item.product].component.address}"
Assuming here that myBean implements Map interface and returns the appropriate object and item.product is returns a string.
I am not sure this will work, but it's your only option beside implementing a getter that looks up item.product value in its implementation.

Invoking methods with parameters by EL in JSF 1.2

I am using a datatable and for each row I have two buttons, an "Edit" and a "Delete".
I need these buttons to be read-only, i.e. disabled, if a certain condition is met for the row in question. I have seen in JSF 2 that it is possible to pass parameters to method calls. Is there anything equivalent in JSF 1.2?
Ideally what I would like it something like (the looping variable is loop and there is another bean, helper, which contains the method I would like to invoke):
<h:commandButton value="Edit"
disabled="#{helper.isEditable(loop.id)}" />
In this case it does not make semantic sense to add an isEditable attribute to the bean and it is not practical to create a wrapper Object around the bean.
Thanks in advance.
I have seen in JSF 2 that it is possible to pass parameters to method calls. Is there anything equivalent in JSF 1.2?
Passing parameters to method calls is not specific to JSF 2. It is specific to EL 2.2, which is in turn part of JSP 2.2 / Servlet 3.0 / Java EE 6. JSF 2 just happens to be part of Java EE 6 as well. In other words, if you deploy your JSF 1.2 web application to a Servlet 3.0 compatible container like Tomcat 7, Glassfish 3, etc and your web.xml is declared conform Servlet 3.0 spec version, then it'll just work out the box for JSF 1.x as well.
If you're however still targeting a container of an older Servlet version, then you need to supply a different EL implementation which supports invoking methods with arguments. One of those implementations is JBoss-EL which you can install by just dropping the jboss-el.jar file in /WEB-INF/lib of your webapp and adding the following context parameter to the web.xml. Here's a Mojarra-specific example (Mojarra is the codename of JSF RI):
<context-param>
<param-name>com.sun.faces.expressionFactory</param-name>
<param-value>org.jboss.el.ExpressionFactoryImpl</param-value>
</context-param>
If you're using MyFaces as JSF implementation, you need the following context parameter instead:
<context-param>
<param-name>org.apache.myfaces.EXPRESSION_FACTORY</param-name>
<param-value>org.jboss.el.ExpressionFactoryImpl</param-value>
</context-param>
See also:
Invoke direct methods or methods with arguments / variables / parameters in EL

Resources