Context Initialization Parameters for Managed Bean - jsf-2

Background
A managed bean must have parameters configured through its web.xml file. The web.xml file defines context initialization parameters that are configured in JDeveloper (11.1.2.3) as follows:
The source for the definition of reporting.server.protocol follows:
<context-param>
<description>Defines the data transport mechanism to ret...</description>
<param-name>reporting.server.protocol</param-name>
<param-value>http</param-value>
</context-param>
The bean exposes public accessor methods for reportServerProtocol.
The source for the bean resembles:
#ManagedBean
#RequestScoped
public class OracleReportBean extends ReportBean {
#ManagedProperty("#{initParam['reporting.server.protocol']}")
private String reportServerProtocol = URLReportImpl.DEFAULT_PROTOCOL;
// ...
}
Problem
I would like to initialize the bean using context initialization parameters, rather than through FacesContext. In adfc-config.xml (note: not faces-confg.xml), some examples show references to initParam:
<managed-bean>
<managed-bean-name>reportBean</managed-bean-name>
<managed-bean-class>ca.corp.report.view.OracleReportBean</managed-bean-class>
<managed-bean-scope>request</managed-bean-scope>
<managed-property>
<property-name>reportServerProtocol</property-name>
<property-class>java.lang.String</property-class>
<value>#{initParam['reporting.server.protocol']}</value>
</managed-property>
...
</managed-bean>
The key line being the value element #{initParam['reporting.server.protocol']}. However, JDeveloper shows the line as being incorrect. That is, the initParam context is not available within adfc-confing.xml.
The error is: "EL token initParam is unknown."
Question
Using an EL, how can the context initialization parameters be used to configure a managed bean, declaratively within ADFc?
Related Links
How to inject entire managed bean via #ManagedProperty annotation?
http://balusc.blogspot.ca/2011/09/communication-in-jsf-20.html
https://stackoverflow.com/tags/el/info
http://www.oracle.com/technetwork/developer-tools/adf/learnmore/43-remote-task-flow-169185.pdf
http://docs.oracle.com/cd/E25178_01/web.1111/b31974/taskflows_activities.htm

A bug in JDeveloper causes errors to be displayed:
However, even though the IDE displays an error, the code executes as expected.

In the ui layer you could try something like this :
<c:set target="${BeanName}" property="PropertyName" value="${true}"/>

Related

SBT ManagedBean property credentialStore is ignored with SmartCloudOAuth2Endpoint

Is seems that the credentialStore property is not being picked up when using the SBT. We have this property:
<managed-property>
<property-name>credentialStore</property-name>
<value>CredStoreCloudant</value>
</managed-property>
There is no change when I change the value to any odd name, while this name is clearly defined in the managed-beans.xml, like this :
<managed-bean>
<managed-bean-name>CredStoreCloudant</managed-bean-name>
<managed-bean-class>com.eoffice.sbt.credentialstore.CloudantCredentialStore</managed-bean-class>
<managed-bean-scope>application</managed-bean-scope>
</managed-bean>
The managed-beans.xml is being used, when we change the property clientID , we do get the 401 error:
oauth_invalid_clientid
Which is expected behaviour.
The OAuth dance is performed nicely, but our code does not execute. It appears to be using the MemoryStore.

CDI/WELD can a custom qualifier work in combination with the #Named annotation?

While having a custom qualifier for CDI support as followed:
#Qualifier
#Retention(RUNTIME)
#Target({METHOD, FIELD, PARAMETER, TYPE})
public #interface QualifiedFooBean {
}
#QualifiedFooBean
public class FooBean implements ImplFooBean {
}
public interface ImplFooBean {
}
I would like to bind FooBean #{fooBean} directly without requiring a wrapper or processor (seen from this example). The annotation "Named" (in class FooBean) seems not to work for my class layout.
My solution (without wrapper) which I'm wondering why it's not working and invoking: Target Unreachable, identifier 'fooBean' resolved to null
#Named
#QualifiedFooBean
public class FooBean implements ImplFooBean {
}
Has anyone any idea?
A wrapper is not needed. My solution is perfectly valid. It's also allowed to add Named in combination of a custom qualifier (in my case QualifiedFooBean). I had to just create an empty beans.xml file in WEB-INF folder in order to get CDI to work. Anyhow The question itself explains how custom qualifiers can work. You can also prefill beans.xml with following content:
<beans xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/beans_1_0.xsd">
</beans>
It will serve as a skeleton for future use, if you need to configure more fancy stuff with CDI.
Adding #Named to your bean should work : it works for me.
In Fact #Named is a qualifier, when JSF resolve the Bean for displaying it does a lokup based on #Named qualifier. In CDI a bean is found if the lookup side (i.e. Injection point) ask for a subset of its Qualifier.
For instance a bean qualified like that :
#QualifiedFooBean
#SecondQualifier
public class FooBean {}
Will be found (if there is no ambiguous resolution) by
#Inject
#SecondQualifier
FooBean bean;
or even :
#Inject
FooBean bean;
But not by
#Inject
#SecondQualifier
#ThirdQualifier
FooBean bean;
So you can add the #Named qualifier and let CDI resolution engine do its job.

jsf 2 managedproperty annotation and parameters

I'm using JSF 2 and Sprig 3, and I want to migrate from using faces-config.xml to annotations.
old one : faces-config.xml :
<managed-bean>
<managed-bean-name>banqueBean</managed-bean-name>
<managed-bean-class>commun.BanqueBean</managed-bean-class>
<managed-bean-scope>request</managed-bean-scope>
<managed-property>
<property-name>banqueService</property-name>
<value>#{banqueService}</value>
</managed-property>
<managed-property>
<property-name>banqueId</property-name>
<value>#{param.banqueId}</value>
</managed-property>
</managed-bean>
new one :
public class BanqueBean{
private Banque banque;
#ManagedProperty(name = "banqueService", value = "#{banqueService}")
private BanqueService banqueService;
#ManagedProperty(value = "#{param.banqueId}")
private String banqueId;
// setters for banqueService and banqueId
the value of banqueId is set using :
<f:param value="#{banque.id}" name="banqueId" />
the problem is that when using faces-config.xml the "System" calls the setter of banqueService before the setter of parameter banqueId so that I can use banqueService inside setBanqueId method.
when using annotations it calls the setter of banqueId before banqueService so that I get null as a value of it.
why it inverses the call of this tow methods?
You should not rely on managed property setter method invocation order at all. This is nowhere definied in the specification.
Just hook at that point when JSF is finished with setting of all managed properties. That's the #PostConstruct annotated method.
#PostConstruct
public void init() {
banque = banqueService.find(banqueId);
}
Stop doing business logic in setters, this is only necessary if you're still using legacy JSF 1.1 which didn't support #PostConstruct.
Unrelated to the concrete problem, are you aware of the new JSF2 <f:viewParam>? It might as well help you to get rid of this boilerplate in the bean and end up having only a Banque property and a reusable Converter.
See also:
ViewParam vs #ManagedProperty(value = "#{param.id}")

To get current Instance of the session scoped bean in Jsf 2.0

i referred to this question and i've a similar problem
JSF - Get the SessionScoped Bean instance
I want to get the current instance of a managed bean in another managed bean. I've a SuperBean which is extended in a base Class - baseBean.
I set the value of a list - itemList in baseBean. The getter setter of the list are in SuperBean and I should use this SuperBean in my BackingBean to get the value of the itemList.
I tried using -
Application app = FacesContext.getCurrentInstance().getApplication();
ValueBinding vb = app.createValueBinding("#{superbean}");
SuperClass superclass = (SuperClass) vb.getValue(FacesContext.getCurrentInstance());
When I try to print superclass.getItems(); - It gives only this - []
And also this -
SuperClass superclass = (SuperClass)FacesContext.getCurrentInstance().
getExternalContext().getSessionMap().get("superbean");
When I try to print with this - It throws exception as my superbean entry is not present in the sessionMap even though the entry is placed in facesConfig and also as #ManagedBean and #sessionscoped
Kindly help me resolve this.
You can inject a managed bean into another if the injected bean has the same or broader scope. Here is an example:
#ManagedBean(name = "oneBean")
#ViewScoped
public class OneBean{
// injections
#ManagedProperty(value = "#{anotherBean}")
private AnotherBean anotherBean;
// don't forget to add getter and setter for anotherBean
...
}

Date conversion exception inside JSF composite component

When I access a JPA managed date value from JSF, it comes back with an javax.faces.component.UdateModelException saying
'Cannot convert 01.01.10 00:00 of type class java.util.Date to class org.apache.openjpa.util.java$util$Date$proxy
Using a JPA-managed date value (which means it is proxied) works fine when it is used directly from the EL likes this:
'<h:outputLabel value="MyDateValue" for="input"/>
'<h:inputText id="inputDate" value="#{bean.myDate}"/>
However, it causes trouble when trying to use it with composite components
and gives back the following converter exception and thus can't update the model...
The (simplified) JSF composite component inputDate.xhtml
<head>
<title>A date input field</title>
</head>
<composite:interface>
<composite:attribute name="dateValue"/>
</composite:interface>
<composite:implementation>
<h:outputLabel value="MyDateValue" for="input"/>
<h:inputText id="input" value="#{cc.attrs.dateValue}"/>
</composite:implementation>
Assumption:
It seems the proxy replacement in OpenJPA is handled differently when the value is being accessed from inside a composite. My guess is the EL-resolver handles calls to object values differently when it is passed to composites. Passing it to composites means it is first accessed within the composite, which is too late and the required replacement of the proxy is not accomplished (thus the converter exception)
So I tried to change the Expression Language for MyFaces, but it didn't work in Websphere, even though I changed the class loading to parent last and provided el-impl and el-api from glassfish in the lib folder and inserted the necessary context-param for MyFaces
How do you guys use JPA-managed dates (or other proxied entities) in composite components???
If you are using the sun EL implementation you might use the following ELResolver which works around this issue:
public class BugfixELResolver extends ELResolver {
//...
#Override
public Class<?> getType(ELContext anElContext, Object aBase, Object aProperty) {
if (aBase.getClass().getCanonicalName().equals("com.sun.faces.el.CompositeComponentAttributesELResolver.ExpressionEvalMap")){
Object tempProperty=((Map)aBase).get(aProperty);
if (tempProperty!=null&&tempProperty.getClass().getCanonicalName().equals("org.apache.openjpa.util.java.util.Date.proxy")) {
anElContext.setPropertyResolved(true);
return java.util.Date.class;
}
}
return null;
}
}
Add it to the faces-config this way:
<el-resolver>
xxx.BugfixELResolver
</el-resolver>
This workaround can also be used in environments where you can not change the EL implementation (like websphere etc.).
Here is the workaround. The problem seems to be WebSpheres' ExpressionLanguage Implementation or rather the order resolvers are executed. Registering the JBoss EL implementation works and resolves the date proxies before calling the composite component. I also tried the Glassfish EL, but it didn't work either...
Registering a alternative EL is quite strange: The setting in web.xml for MyFaces is
<context-param>
<param-name>org.apache.myfaces.EXPRESSION_FACTORY</param-name>
<param-value>org.jboss.el.ExpressionFactoryImpl</param-value>
</context-param>
Additionally under WebContent/META-INF/services/ a file named javax.el.expressionFactory is needed with this single line org.jboss.el.ExpressionFactoryImpl. The class comes from jboss-el-2.0.2.CR1.jar
(sorry, couldn't find the link to a maven repo)
I will keep you updated once I find a better solution...

Resources