[ 
https://issues.apache.org/jira/browse/MYFACES-1999?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=12636288#action_12636288
 ] 

Tony Robertson commented on MYFACES-1999:
-----------------------------------------

An alternative (or complimentary) approach is to resolve the property name 
based on the available guice bindings that have been annotated with the same 
name. For example:

                Object value = null;
                for (Key<?> key : injector.getBindings().keySet()) {
                        Annotation ann = key.getAnnotation();
                        if (ann instanceof Named
                                        && managedBeanName.equals(((Named) 
ann).value())) {
                                value = injector.getInstance(key);
                                log.info("Instantiated " + managedBeanName + " 
using binding "
                                                + key + ", new instance is ("
                                                + value.getClass().getName() + 
") " + value);
                                break;
                        }
                }

(this could be cached to make it more efficient for repeated lookup).
This has the advantage that you don't even have to define your managed beans in 
faces-config.xml for them to be available to your EL resolver. Just use the 
"annotatedWith" when defining the guice module.

If you do still want to define them in faces-config.xml (perhaps for migration 
support, or for tool support), a neat way to combine would be to define a guice 
module as shown below. That way, any beans defined in the faces-confg don't 
need to be manually added to a guice module, and any guice managed class can 
also have faces beans injected by using @Inject @Named("myfacebean") ...
Here is a first cut for the guice module:
---------------------------------
package au.com.saltgroup.web.support;

import javax.servlet.ServletContext;

import org.apache.myfaces.config.RuntimeConfig;
import org.apache.myfaces.config.element.ManagedBean;

import com.google.inject.AbstractModule;
import com.google.inject.Scopes;
import com.google.inject.TypeLiteral;
import com.google.inject.binder.ScopedBindingBuilder;
import com.google.inject.name.Names;
import com.google.inject.servlet.ServletScopes;

public class FacesManagedBeansGuiceModule extends AbstractModule {

        private RuntimeConfig runtimeConfig;

        public FacesManagedBeansGuiceModule(ServletContext context) {
                runtimeConfig = (RuntimeConfig) context
                                .getAttribute(RuntimeConfig.class.getName());
        }

        @Override
        protected void configure() {
                for (ManagedBean mb : runtimeConfig.getManagedBeans().values()) 
{
                        @SuppressWarnings("unchecked")
                        ScopedBindingBuilder sbb = 
bind(mb.getManagedBeanClass())
                                        
.annotatedWith(Names.named(mb.getManagedBeanName())).to(
                                                        
TypeLiteral.get(mb.getManagedBeanClass()));
                        String s = mb.getManagedBeanScope();
                        if ("application".equals(s)) {
                                sbb.in(Scopes.SINGLETON);
                        } else if ("session".equals(s)) {
                                sbb.in(ServletScopes.SESSION);
                        } else if ("request".equals(s)) {
                                sbb.in(ServletScopes.REQUEST);
                        }
                }
        }
}




> In GuiceResolver managed-bean-scope is ignored, scope defaults to none
> ----------------------------------------------------------------------
>
>                 Key: MYFACES-1999
>                 URL: https://issues.apache.org/jira/browse/MYFACES-1999
>             Project: MyFaces Core
>          Issue Type: Bug
>          Components: JSR-252
>    Affects Versions: 1.2.4
>         Environment: Tomcat 6
>            Reporter: Tony Robertson
>            Priority: Minor
>
> The problem with the current 
> org.apache.myfaces.el.unified.resolver.GuiceResolver is that it doesn't take 
> into account the managed-bean-scope from the ManagedBean configuration. 
> Typically you end up with multiple instances of the managed bean (a new one 
> every time the resolver is called) -- ie, same as a managed-bean-scope of 
> "none".
> Note, there is some code in the resolver like this:
>     if (ectx == null || 
>             ectx.getRequestMap().containsKey(property) || 
>             ectx.getSessionMap().containsKey(property) ||
>             ectx.getApplicationMap().containsKey(property) ) 
>             return null;
> This works if there is _already_ a request, session or application scope 
> attribute with the given name, but if not, the managed bean is not added to 
> the scope. You can see that the overriden "getValue" method from the 
> ManagedBeanResolver was actually responsible for putting any new object into 
> the scope via the "putInScope" method.
> The simplest way to fix this in the code seems to be to make the 
> ManagedBeanResolver.putInScope method "protected" (rather than private), and 
> then call it from the GuiceResolver.getValue method whenever a new value is 
> obtained from the injector.
> Meanwhile, a work-around is to leverage the guice-servlet module and then to 
> specify the scope in the guice module, something like this:
>     bind(HelloWorldBacking.class).in(ServletScopes.REQUEST);
> However, for that you have to list all your managed beans in two places 
> (faces-config.xml as well as your guice module), and also have to add the 
> com.google.inject.servlet.GuiceFilter filter class to your web app.

-- 
This message is automatically generated by JIRA.
-
You can reply to this email to add a comment to the issue online.

Reply via email to