Extract instance of the bean that is getting the injected field from an InjectionPoint - cdi

In an InjectionPoint injectionPoint, we can obtain the class of the bean that is getting the injected field just by:
Bean<?> bean = injectionPoint.getBean();
String beanClass = bean.getBeanClass();
Is there a way to extract the instance of the bean that is getting the injected field?

Related

Is it possible to inject a view scoped bean into a #FacesValidator in JSF?

As the title implies, I'm trying to inject a view scoped bean into a validator decorated by #FacesValidator as follows.
#FacesValidator(value = "priceRangeValidator")
public final class PriceRangeValidator implements Validator {
#ManagedProperty(value="#{rangeSliderBean}")
private RangeSliderBean rangeSliderBean; //Setter only.
#Override
public void validate(FacesContext context, UIComponent component, Object value) throws ValidatorException {
// The bean instance is unavailable here. It is null.
}
}
The target view scoped bean - RangeSliderBean is unavailable in the validate() method.
I'm temporarily following the following way to get an instance of that bean in the validate() method itself.
RangeSliderBean rangeSliderBean = context.getApplication().evaluateExpressionGet(context, "#{rangeSliderBean}", RangeSliderBean.class);
Is it possible to inject a view scoped JSF managed bean into a validator using the #ManagedProperty annotation or something else?
I'm using JSF 2.2.6.
UPDATE:
This does not work on Mojarra 2.3.0-m01. The bean instance still remains null as it did before. This time long after this post, I took a corresponding view scoped CDI bean (#ManagedProperty was replaced by #Inject).
Try dynamic Injection by evaluating an expression using Application like this.
FacesContext facesContext = FacesContext.getCurrentInstance();
RangeSliderBean rangeSliderBean = facesContext.getApplication().evaluateExpressionGet(facesContext, "#{rangeSliderBean}", RangeSliderBean .class);

JSF selectOneMenu - setting value in bean

I have selectOneMenu
<h:selectOneMenu id = "current" value = "#{helloBean.currentLanguage}">
<f:selectItems value="#{helloBean.categoryLanguages}"></f:selectItems>
<f:ajax render = "ccData"></f:ajax>
</h:selectOneMenu>
Here is HelloBean
#ManagedBean(name="helloBean")
#SessionScoped
public class HelloBean implements Serializable {
private String currentLanguage;
public void setcurrentLanguage(String currentLanguage){
this.currentLanguage = currentLanguage;
}
}
I have a problem with setting of currentLanguage. Eclipse shows an error message that #{helloBean.currentLanguage} expression is not settable. And when I run my project, I get an error
javax.servlet.ServletException: /hello.xhtml #19,74 value="#{helloBean.currentLanguage}": Property 'currentLanguage' not readable on type java.lang.String
As BalusC pointed out, Java is case sensitive.
So when you write: value=#{helloBean.currentLanguage} JSF expects that you define a setter and a getter of that attribute (currentLanguage):
public void setCurrentLanguage(String language){
this.currentLanguage = language;//Or whatever
}
(Notice the upper C in current. And add a getter)
Since you are using Eclipse, try to automatically generate access methods of your classes. (Right click -> source -> generate getter and setters)

PrimeFaces <p:poll> refresh invalidates backing bean member if bean ViewScoped

I am using PrimeFaces UI library and JSF 2.
I have a backing bean:
public class JobMgmtBean extends ClientBeanBase implements Serializable
and
public class ClientBeanBase extends BeanBase
(so inheritance is JobMgmtBean:ClientBeanBase:BeanBase).
I wanted to set my JobMgmtBean from request scoped to view scoped, but after a while my sessionVars which is defined in BeanBase becomes null and the bean is not functional anymore.
I initialize sessionVars in the BeanBase like this:
protected Map<String,Object> sessionVars = null;
ex = FacesContext.getCurrentInstance().getExternalContext();
sessionVars = ex.getSessionMap();
I refresh some of my PrimeFaces UI components on the page every 5 seconds (using <p:poll interval="5"...>), and after a few refreshes sessionVars becomes null.
Why does this happen?
You can use View scope provided you can assemble the state of object during de-serialization.
Java provides method hooks for a serializable class where you can perform custom logic.
private void writeObject(java.io.ObjectOutputStream stream) throws java.io.IOException {
//custom logic
stream.defaultWriteObject();
}
private void readObject(java.io.ObjectInputStream stream) throws java.io.IOException, ClassNotFoundException {
stream.defaultReadObject();
// custom logic
}
Any bean reference you think you dont want serialize you can mark it as transient.
private transient Bean bean.
this bean wont get serialized but the problem is you are responsible
to set the reference back when it is deserailized in method hook
"readObject"
private void readObject(java.io.ObjectInputStream stream) throws java.io.IOException, ClassNotFoundException {
stream.defaultReadObject();
// custom logic
this.bean = ................
}
ViewScoped beans require objects to be Serialized, and my class extends many classes with too many object which all need to be Serialized which is not possible. This means that I can not use ViewScoped at all here.

When seam #Out annotation works?

I hava a class below;
package org.domain.emlakprojesi.session;
import java.util.List;
import javax.persistence.EntityManager;
import org.domain.emlakprojesi.entity.ziyaretci;
import org.jboss.seam.ScopeType;
import org.jboss.seam.annotations.In;
import org.jboss.seam.annotations.Logger;
import org.jboss.seam.annotations.Name;
import org.jboss.seam.annotations.Out;
import org.jboss.seam.log.Log;
import org.jboss.seam.security.Credentials;
import org.jboss.seam.security.Identity;
#Name("authenticator")
public class Authenticator
{
#Logger private Log log;
#In Identity identity;
#In Credentials credentials;
#In EntityManager entityManager;
#Out(scope =ScopeType.SESSION,required=false) ziyaretci girisYapanZiyaretci;
public boolean authenticate()
{
log.info("authenticating {0}", credentials.getUsername());
List<ziyaretci> ziyaretciler =entityManager.createQuery("from Ziyaretci where email = #{credentials.username} and sifre = #{credentials.password}").getResultList();
if(ziyaretciler.size() == 1){
this.setGirisyapanziyaretci(ziyaretciler.get(0));
return true;
}else
return false;
}
public void setGirisyapanziyaretci(ziyaretci girisyapanziyaretci) {
this.girisYapanZiyaretci= girisyapanziyaretci;
}
public ziyaretci getGirisyapanziyaretci() {
return girisYapanZiyaretci;
}
}
I am setting the girisYapanZiyaretci in authenticate method
when I run the application I am getting null pointer exception
I actually ask when #In and #Out annotations work?
Injection with #In and the so-called outjection with #Out work before and after the method call.
All #In properties are injected before the method is invoked, and all #Out properties are set in the defined context after the invocation, unless the method raised an exception.
Session scope is broader than the event scope, so if a session scoped beans is injected in an event scoped bean, the event scope (and the event scoped bean) is destroyed before the session scoped bean.
On the contrary, if an event scoped bean is injected in a session scoped bean (or in any other broader scope context), the value is injected before the method call and set to null after the method call.
Regarding injection and JSF phases, injection happens after the update model values phase and inside the invoke application phase. #Filter and #Converter break this rule, though.
#In annotation gets tree parameters: value, create and required
In Seam documantation there is brief explanation en examples.
Specifies that a component attribute is to be injected by evaluating a
JSF EL expression at the beginning of each component invocation.
value — specifies the name of the context variable. Default to the
name of the component attribute. Alternatively, specifies a JSF EL
expression, surrounded by #{...}.
create — specifies that Seam should instantiate the component with the
same name as the context variable if the context variable is undefined
(null) in all contexts. Default to false.
required — specifies Seam should throw an exception if the context
variable is undefined in all contexts.
Maybe create parameter, which creates Context Variable if it is null, helps you about your problem.
#In(create = true)

how to get http get request params in jsf 2.0 bakcing bean?

I having trouble with passing http get parameters to jsf 2.0 backing bean.
User will invoke URl with some params containing id of some entity, which is later used to persist some other entity in db.
whole process can be summarized by fallowing:
1. user open page http://www.somhost.com/JsfApp/step-one.xhtml?sid=1
2. user fills some data and goes to next page
3. user fills some more data and then entity is saved to db with sid param from step one.
I have session scoped backing bean that hold data from all the pages (steps), but I cant pass param to bean property..
any ideas?
That's only possible if the bean is request scoped since it's a request parameter. Create a request scoped bean and make the current session scoped bean a managed property of it as well.
#ManagedBean
#RequestScoped
public class Step {
#ManagedProperty(value="#{param.sid}")
private Long sid;
#ManagedProperty(value="#{data}")
private Data data; // #{data} is a #SessionScoped #ManagedBean
public String submitStep1() {
// ...
}
public String submitStep2() {
// ...
}
// ...
}

Resources