I am using primefaces version 5 and I am adding messages regarding to a specific actions like save :
public void save(Tenant tenant) {
tenantDao.save(tenant);
FacesContext.getCurrentInstance().addMessage(null, new FacesMessage("Save success"));
}
Since I had a lot of these actions I tried to simplify this by creating a custom annotation called Message:
#Target(Runtime)
#Retention(Method)
public #interface Message {
String value();
}
and in my dao class :
public class TenantDao {
#Message("Saved Successfully")
public Tenant save(Tenant t) {
return em.save(t);
}
}
To read this annotation I have overridden the ELResolver the method invoke
public Object invoke(ELContext context,
Object base,
Object method,
Class<?>[] paramTypes,
Object[] params) {
Object result = super.invoke(context,method,paramTypes,params);
Method m = base.getClass().getMethod(method,paramTypes);
if(m.getAnnotation(Message.class) != null) {
addMessahe(m.getAnnotation(Message.class).value());
}
return result;
}
This was called in property (rendered, update, ..) but not in action listener
After a lot of debugging I discovered that theactionListener is called from MethodExpression class. So, I wrapped the MethodExpression class, and override the method invoke.
The problem now is that there are no way to retreive the class Method from MethodExpression class, also if I used the expression #{tenantDao.save(tenant)} the method getMethodInfo from MethodExpression will throw an exception.
Are there any way to read tAnnotation from any jsf context ?
I know that using Spring with AOP may solve this but I am not using Spring now.
Thanks
Related
I'm currently upgrading our libraries to JavaEE 7 and I have some questions on how to lookup and create (unmanaged) bean instances. I've looked around some other questions here and on the internet and found quite different solutions. I've ignored qualifiers on my examples.
In the old implementation (for CDI 1.0) of the libraries I've only used Lookup #1 - even for #Dependent.
Lookup #1: The old way using BeanManager#getBeans()
public static <T> T getBean(Class<T> clazz) {
Bean<T> bean = (Bean<T>) _beanManager.resolve(_beanManager.getBeans(clazz));
if(bean.getScope().equals(Dependent.class)) {
throw new IllegalArgumentException("Cdi#getBean(Class) should only be invoked for classes that do not belong to the "
+ "#Dependent scope");
}
CreationalContext<T> ctx = _beanManager.createCreationalContext(bean);
return (T) _beanManager.getReference(bean, clazz, ctx);
}
I've added the if-statement because I've read at some other place, that #Dependent scoped beans shouldn't be created on this way (no well-defined lifecycle).
Lookup #2: The CDI-1.1-way
public static <T> T getBean(Class<T> clazz) {
return CDI.current().select(clazz).get();
}
Q1: Which one (#1 or #2) should be preferred in CDI 1.1 to perform programmatic lookup of managed beans? Any pros and cons? Other solutions available?
Dependent / Creation #1: Use Unmanged and UnmanangedInstance
public static <T> UnmanagedInstance<T> getDependentBean(Class<T> clazz) {
return new Unmanaged<>(clazz).newInstance();
}
The UnmanagedInstance could be wrapped in a class DependentProvider which calls produce(), inject(), postConstruct() in the constructor and preDestroy(), dispose() in the destroy method (to simplify the usage even more).
Dependent / Creation #2: Inspired by DeltaSpike
public static <T> DependentProvider<T> getDependentBean(Class<T> clazz) {
Bean<T> bean = (Bean<T>) _beanManager.resolve(_beanManager.getBeans(clazz));
CreationalContext<T> ctx = _beanManager.createCreationalContext(bean);
T instance = (T) _beanManager.getReference(bean, clazz, ctx);
return new DependentProvider<T>(bean, ctx, instance);
}
The returned provider has a destroy() method, to remove the created instance.
public void destroy() {
bean.destroy(instance, creationalContext);
}
What I'm missing in the implementation from DeltaSpike is the call to creationalContext.release(). Is this not required?
Creation #3: Instance => only possible in managed beans
#ViewScoped
class X implements Serializable {
#Inject Instance<MyObject> _myObjectProvider;
public void doSomething() {
MyObject obj = _myObjectProvider.get();
// ... work with obj
// call _myObjectProvider.destroy(obj) as soon as we're done with the instance of MyObject.
}
}
Q2: Again, which one (#1 or #2, #3) should be preferred for programmatic creation of unmanaged "beans"? Any pros and cons? Other solutions available?
Finally I have a question on how to check if a bean is already instantiated (e.g. a session scoped bean) or not. I came up with the following method (for non-#Dependant only):
public <T> boolean existsBeanInstance(String name) {
Bean<T> bean = (Bean<T>) _beanManager.resolve(_beanManager.getBeans(name));
Context beanScopeContext = _beanManager.getContext(bean.getScope());
return beanScopeContext.get(bean) != null;
}
Q3: Is this reliable?
i have the following code.
#Configuration
#EnableAsync
#EnableScheduling
public class AsyncConfiguration implements AsyncConfigurer {
#Override
public Executor getAsyncExecutor() {
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
executor.setCorePoolSize(2);
executor.setMaxPoolSize(50);
executor.setQueueCapacity(10000);
executor.setThreadNamePrefix("Executor-");
executor.initialize();
return executor;
}
}
and if i want to run the recommend method after every certain interval of time. What can be the java spring bean configuration way to do that.?
public class UserBrandsRecommender {
public List<RecommendedItem> recommend(Long userId, int number) throws TasteException{
}
}
You should look into the #Scheduled annotation. For example:
#Scheduled(fixedDelay=5000)
public void doSomething() {
// something that should execute periodically
}
You'll probably need to create a new Spring bean with a method similar to above. The bean could have the UserBrandsRecommender injected into it. The new bean will need to implement some logic to pass proper values for the "userId" and "number" parameters to the "recommend" method.
More information here:
http://docs.spring.io/spring/docs/3.2.x/spring-framework-reference/htmlsingle/#scheduling-annotation-support
I'm trying to create a dynamic object that can be used as a component of a static object. Here is a contrived example of what I'm trying to accomplish.
Here is the dynamic component:
public class DynamicComponent : DynamicObject
{
public override bool TryInvokeMember(
InvokeMemberBinder binder,
object[] args,
out object result)
{
result = "hello";
return true;
}
}
And here is a class where inheriting from DynamicObject isn't an option...assume that there is some third party class that I'm forced to inherit from.
public class AStaticComponent : VendorLibraryClass, IDynamicMetaObjectProvider
{
IDynamicMetaObjectProvider component = new DynamicComponent();
public DynamicMetaObject GetMetaObject(Expression parameter)
{
var result = component.GetMetaObject(parameter);
return result;
}
}
The direct usage of DynamicComponent works:
dynamic dynamicComponent = new DynamicComponent();
Assert.AreEqual(dynamicComponent.AMethod(), "hello");
However, forwarding the GetMetaObject through AStaticComponent causes some form of an infinite loop.
dynamic dynamicComponent = new AStaticComponent();
Assert.AreEqual(dynamicComponent.AMethod(), "hello"); //causes an infinite loop
Anyone know why this occurs?
And if it's some baked in behavior of DynamicObject that I cannot change, could someone provide some help on how to create a IDynamicMetaObjectProvider from scratch to accomplish a component based dynamic object (just something to get things started)?
I think the problem is that the Expression parameter passed to GetMetaObject represents the target of the dynamic invocation (i.e. the current object). You are passing the outer object to the call on component.GetMetaObject, so the returned meta object is trying to resolve the call to AMethod on the outer object instead of itself, hence the infinite loop.
You can create your own meta object which delegates to the inner component when binding member invocations:
public class AStaticComponent : VendorLibraryClass, IDynamicMetaObjectProvider
{
IDynamicMetaObjectProvider component = new DynamicComponent();
public DynamicMetaObject GetMetaObject(Expression parameter)
{
return new DelegatingMetaObject(component, parameter, BindingRestrictions.GetTypeRestriction(parameter, this.GetType()), this);
}
private class DelegatingMetaObject : DynamicMetaObject
{
private readonly IDynamicMetaObjectProvider innerProvider;
public DelegatingMetaObject(IDynamicMetaObjectProvider innerProvider, Expression expr, BindingRestrictions restrictions)
: base(expr, restrictions)
{
this.innerProvider = innerProvider;
}
public DelegatingMetaObject(IDynamicMetaObjectProvider innerProvider, Expression expr, BindingRestrictions restrictions, object value)
: base(expr, restrictions, value)
{
this.innerProvider = innerProvider;
}
public override DynamicMetaObject BindInvokeMember(InvokeMemberBinder binder, DynamicMetaObject[] args)
{
var innerMetaObject = innerProvider.GetMetaObject(Expression.Constant(innerProvider));
return innerMetaObject.BindInvokeMember(binder, args);
}
}
}
#Lee's answer is really useful, I wouldn't have known where to get started without it. But from using it in production code, I believe it has a subtle bug.
Dynamic calls are cached at the call site, and Lee's code produces a DynamicMetaObject which effectively states that the inner handling object is a constant. If you have a place in your code where you call a dynamic method on an instance of AStaticObject, and later the same point in the code calls the same method on a different instance of AStaticObject (i.e. because the variable of type AStaticObject now has a different value) then the code will make the wrong call, always calling methods on the handling object from the first instance encountered at that place in the code during that run of the code.
This is a like-for-like replacement, the key difference being the use of Expression.Field to tell the dynamic call caching system that the handling object depends on the parent object:
public class AStaticComponent : VendorLibraryClass, IDynamicMetaObjectProvider
{
IDynamicMetaObjectProvider component = new DynamicComponent();
public DynamicMetaObject GetMetaObject(Expression parameter)
{
return new DelegatingMetaObject(parameter, this, nameof(component));
}
private class DelegatingMetaObject : DynamicMetaObject
{
private readonly DynamicMetaObject innerMetaObject;
public DelegatingMetaObject(Expression expression, object outerObject, string innerFieldName)
: base(expression, BindingRestrictions.Empty, outerObject)
{
FieldInfo innerField = outerObject.GetType().GetField(innerFieldName, BindingFlags.Instance | BindingFlags.NonPublic);
var innerObject = innerField.GetValue(outerObject);
var innerDynamicProvider = innerObject as IDynamicMetaObjectProvider;
innerMetaObject = innerDynamicProvider.GetMetaObject(Expression.Field(Expression.Convert(Expression, LimitType), innerField));
}
public override DynamicMetaObject BindInvokeMember(InvokeMemberBinder binder, DynamicMetaObject[] args)
{
return binder.FallbackInvokeMember(this, args, innerMetaObject.BindInvokeMember(binder, args));
}
}
}
I have a collection of Processor beans in my application along with a factory for creating them.
public abstract class Processor {
public Processor(String config) { .... }
public abstract void process() throws Exception;
}
public class Processor1 extends Processor {
public Processor1(String config) { super(config);..}
public void process() {....}
}
public Processor newProcessor(String impl, String config) {
// use reflection to create processor
}
Can I use CDI to replace the factory class/method? And instead use a #Produces?
I tried using the following to iterate or select the instance I wanted. But Weld tells me that allProcessorInstances.isUnsatisfied() == true. I had to create default no-args ctor in order for Weld to find my Processor subclasses.
#Inject #Any Instance<Processor> allProcessorInstances;
Is there any way to tell the CDI container to use the constructor I want it to use? Or am I thinking about this problem the wrong way?
To use the constructor you'd need to annotate it with #Inject, however, every param on the constructor must itself be a bean or something in the CDI scopes.
Using a producer method and having that take an InjectionPoint as a param, then having your configuration be part of an annotation would work.
Writing a simple JSF application I've some across the following Problem:
My entities.controller.EntityNameManager class contains a method getEntityNameSelectList() which I can use to populate a ComboBox with. This works and shows all Entities, since the Method to retrieve the Entities does not have a where clause.
This Method was automatically created.
Now I want to have a second similar Method, that filters the options based on a variable in the sessionscope. To do this I copied the original Method, renamed it to getEntityNameSelectListByUser(User theUser) and changed the Method that queries the database to one that does indeed filter by UserId.
However, when trying to load the page in the browser, I get an error stating that the controller class does not have a "EntityNameSelectListByUser" property. I assume that since my new method expects a parameter it can't be found. Is there a way I can make it aware of the Parameter or the Sessionscope userid?
Support for parameters in EL is slated for the next maintenance release of JSR 245 (announcement here; implementation here).
Assuming you don't want to wait for JEE6, you have several ways to overcome this limitation. These approached are defined in terms of POJO managed beans, so adapt them to your EJBs as appropriate.
1.
Do the session lookup and function call in a backing bean:
public String getFoo() {
FacesContext context = FacesContext
.getCurrentInstance();
ExternalContext ext = context.getExternalContext();
String bar = (String) ext.getSessionMap().get("bar");
return getFoo(bar);
}
Example binding:
#{paramBean.foo}
2.
Use an EL function (defined in a TLD, mapped to a public static method):
public static String getFoo(ParamBean bean, String bar) {
return bean.getFoo(bar);
}
Example binding:
#{baz:getFoo(paramBean, bar)}
3.
Subvert the Map class to call the function (a bit of a hack and limited to one parameter):
public Map<String, String> getFooMap() {
return new HashMap<String, String>() {
#Override
public String get(Object key) {
return getFoo((String) key);
}
};
}
Example binding:
#{paramBean.fooMap[bar]}