You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@myfaces.apache.org by ja...@apache.org on 2011/04/28 00:31:44 UTC

svn commit: r1097264 - in /myfaces/core/trunk/impl/src/main/java/org/apache/myfaces: config/ManagedBeanBuilder.java el/unified/resolver/ManagedBeanResolver.java el/unified/resolver/ScopedAttributeResolver.java webapp/AbstractFacesInitializer.java

Author: jakobk
Date: Wed Apr 27 22:31:44 2011
New Revision: 1097264

URL: http://svn.apache.org/viewvc?rev=1097264&view=rev
Log:
MYFACES-3116 MyFaces cannot resolve @ManagedProperty on startup, throws UnsupportedOperationException (fix + refactoring)

Modified:
    myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/config/ManagedBeanBuilder.java
    myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/el/unified/resolver/ManagedBeanResolver.java
    myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/el/unified/resolver/ScopedAttributeResolver.java
    myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/webapp/AbstractFacesInitializer.java

Modified: myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/config/ManagedBeanBuilder.java
URL: http://svn.apache.org/viewvc/myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/config/ManagedBeanBuilder.java?rev=1097264&r1=1097263&r2=1097264&view=diff
==============================================================================
--- myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/config/ManagedBeanBuilder.java (original)
+++ myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/config/ManagedBeanBuilder.java Wed Apr 27 22:31:44 2011
@@ -18,29 +18,6 @@
  */
 package org.apache.myfaces.config;
 
-import java.lang.reflect.Array;
-import java.lang.reflect.InvocationTargetException;
-import java.util.ArrayList;
-import java.util.Comparator;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import java.util.logging.Level;
-import java.util.logging.Logger;
-
-import javax.el.ELContext;
-import javax.el.ELException;
-import javax.el.ELResolver;
-import javax.el.ExpressionFactory;
-import javax.el.ValueExpression;
-import javax.faces.FacesException;
-import javax.faces.application.Application;
-import javax.faces.application.ProjectStage;
-import javax.faces.context.ExternalContext;
-import javax.faces.context.FacesContext;
-import javax.naming.NamingException;
-
 import org.apache.commons.beanutils.PropertyUtils;
 import org.apache.myfaces.config.annotation.LifecycleProvider;
 import org.apache.myfaces.config.annotation.LifecycleProvider2;
@@ -51,9 +28,32 @@ import org.apache.myfaces.config.element
 import org.apache.myfaces.config.element.ManagedProperty;
 import org.apache.myfaces.config.element.MapEntries;
 import org.apache.myfaces.config.element.MapEntry;
+import org.apache.myfaces.context.servlet.StartupServletExternalContextImpl;
 import org.apache.myfaces.shared_impl.util.ClassUtils;
 import org.apache.myfaces.util.ContainerUtils;
 
+import javax.el.ELContext;
+import javax.el.ELException;
+import javax.el.ELResolver;
+import javax.el.ExpressionFactory;
+import javax.el.ValueExpression;
+import javax.faces.FacesException;
+import javax.faces.application.Application;
+import javax.faces.application.ProjectStage;
+import javax.faces.context.ExternalContext;
+import javax.faces.context.FacesContext;
+import javax.naming.NamingException;
+import java.lang.reflect.Array;
+import java.lang.reflect.InvocationTargetException;
+import java.util.ArrayList;
+import java.util.Comparator;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
 
 /**
  * Create and initialize managed beans
@@ -146,18 +146,11 @@ public class ManagedBeanBuilder
     @SuppressWarnings("unchecked")
     public Object buildManagedBean(FacesContext facesContext, ManagedBean beanConfiguration) throws FacesException
     {
-
-        /*final AnnotatedManagedBeanHandler handler = new AnnotatedManagedBeanHandler(bean,
-                  beanConfiguration.getManagedBeanScope(), beanConfiguration.getManagedBeanName());
-
-          final boolean threwUnchecked = handler.invokePostConstruct();
-
-          if(threwUnchecked)
-              return null;*/
         try
         {
-            LifecycleProvider lifecycleProvider =
-                    LifecycleProviderFactory.getLifecycleProviderFactory(facesContext.getExternalContext()).getLifecycleProvider(facesContext.getExternalContext());
+            ExternalContext externalContext = facesContext.getExternalContext();
+            LifecycleProvider lifecycleProvider = LifecycleProviderFactory
+                    .getLifecycleProviderFactory( externalContext).getLifecycleProvider(externalContext);
             
             final Object bean = lifecycleProvider.newInstance(beanConfiguration.getManagedBeanClassName());
 
@@ -537,13 +530,19 @@ public class ManagedBeanBuilder
         }
 
         // not found so far - check all scopes
-        if (externalContext.getRequestMap().get(beanName) != null)
-        {
-            return REQUEST;
-        }
-        if (externalContext.getSessionMap().get(beanName) != null)
+        final boolean startup = (externalContext instanceof StartupServletExternalContextImpl);
+        if (!startup)
         {
-            return SESSION;
+            // request and session maps are only available at runtime - not at startup
+            // (the following code would throw an UnsupportedOperationException).
+            if (externalContext.getRequestMap().get(beanName) != null)
+            {
+                return REQUEST;
+            }
+            if (externalContext.getSessionMap().get(beanName) != null)
+            {
+                return SESSION;
+            }
         }
         if (externalContext.getApplicationMap().get(beanName) != null)
         {
@@ -555,9 +554,7 @@ public class ManagedBeanBuilder
         }
 
         //not found - check mangaged bean config
-
         ManagedBean mbc = getRuntimeConfig(facesContext).getManagedBean(beanName);
-
         if (mbc != null)
         {
             // managed-bean-scope could be a EL ValueExpression (since 2.0)
@@ -573,9 +570,8 @@ public class ManagedBeanBuilder
                 }
                 else
                 {
-                    return getNarrowestScope(facesContext, 
-                                             mbc.getManagedBeanScopeValueExpression(facesContext)
-                                                 .getExpressionString());
+                    String scopeExpression = mbc.getManagedBeanScopeValueExpression(facesContext).getExpressionString();
+                    return getNarrowestScope(facesContext, scopeExpression);
                 }
             }
             else

Modified: myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/el/unified/resolver/ManagedBeanResolver.java
URL: http://svn.apache.org/viewvc/myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/el/unified/resolver/ManagedBeanResolver.java?rev=1097264&r1=1097263&r2=1097264&view=diff
==============================================================================
--- myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/el/unified/resolver/ManagedBeanResolver.java (original)
+++ myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/el/unified/resolver/ManagedBeanResolver.java Wed Apr 27 22:31:44 2011
@@ -18,14 +18,10 @@
  */
 package org.apache.myfaces.el.unified.resolver;
 
-import java.beans.FeatureDescriptor;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import java.util.logging.Level;
-import java.util.logging.Logger;
+import org.apache.myfaces.config.ManagedBeanBuilder;
+import org.apache.myfaces.config.RuntimeConfig;
+import org.apache.myfaces.config.element.ManagedBean;
+import org.apache.myfaces.context.servlet.StartupServletExternalContextImpl;
 
 import javax.el.ELContext;
 import javax.el.ELException;
@@ -37,10 +33,14 @@ import javax.faces.application.ProjectSt
 import javax.faces.component.UIViewRoot;
 import javax.faces.context.ExternalContext;
 import javax.faces.context.FacesContext;
-
-import org.apache.myfaces.config.ManagedBeanBuilder;
-import org.apache.myfaces.config.RuntimeConfig;
-import org.apache.myfaces.config.element.ManagedBean;
+import java.beans.FeatureDescriptor;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.logging.Level;
+import java.util.logging.Logger;
 
 /**
  * See JSF 1.2 spec section 5.6.1.2
@@ -161,9 +161,11 @@ public class ManagedBeanResolver extends
     public Object getValue(final ELContext context, final Object base, final Object property)
         throws NullPointerException, PropertyNotFoundException, ELException
     {
-
+        // we only resolve ManagedBean instances, not properties of those  
         if (base != null)
+        {
             return null;
+        }
 
         if (property == null)
         {
@@ -172,31 +174,59 @@ public class ManagedBeanResolver extends
 
         final FacesContext facesContext = facesContext(context);
         if (facesContext == null)
+        {
             return null;
-        
+        }
         final ExternalContext extContext = facesContext.getExternalContext();
         if (extContext == null)
+        {
             return null;
+        }
+
+        final boolean startup = (extContext instanceof StartupServletExternalContextImpl);
         
-        if (extContext.getRequestMap().containsKey(property))
-            return null;
-        
+        // request scope (not available at startup)
+        if (!startup)
+        {
+            if (extContext.getRequestMap().containsKey(property))
+            {
+                return null;
+            }
+        }
+
+        // view scope
         UIViewRoot root = facesContext.getViewRoot();
         if (root != null)
         {
             Map<String, Object> viewMap = root.getViewMap(false);
             if (viewMap != null && viewMap.containsKey(property))
+            {
                 return null;
+            }
         }
-        if (extContext.getSessionMap().containsKey(property))
-            return null;
+
+        // session scope (not available at startup)
+        if (!startup)
+        {
+            if (extContext.getSessionMap().containsKey(property))
+            {
+                return null;
+            }
+        }
+
+        // application scope
         if (extContext.getApplicationMap().containsKey(property))
+        {
             return null;
+        }
 
+        // not found in standard scopes - get ManagedBean metadata object
+        // In order to get the metadata object, we need property to be the managed bean name (--> String)
         if (!(property instanceof String))
+        {
             return null;
-
-        final String strProperty = (String)property;
+        }
+        final String strProperty = (String) property;
 
         final ManagedBean managedBean = runtimeConfig(context).getManagedBean(strProperty);
         Object beanInstance = null;
@@ -204,12 +234,11 @@ public class ManagedBeanResolver extends
         {
             context.setPropertyResolved(true);
             
-            // managed-bean-scope could be a ValueExpression pointing to a Map (since 2.0)
+            // managed-bean-scope could be a ValueExpression pointing to a Map (since 2.0) --> custom scope
             if (managedBean.isManagedBeanScopeValueExpression())
             {
                 // check for cyclic references in custom scopes, if we are not in Production stage
-                boolean checkCyclicReferences = 
-                        facesContext.getApplication().getProjectStage() != ProjectStage.Production;
+                boolean checkCyclicReferences = !facesContext.isProjectStage(ProjectStage.Production);
                 List<String> cyclicReferences = null;
                 
                 if (checkCyclicReferences)
@@ -259,7 +288,8 @@ public class ManagedBeanResolver extends
                     }
                 }
             }
-            
+
+            // not found in any scope - create instance!
             if (beanInstance == null)
             {
                 beanInstance = createManagedBean(managedBean, facesContext);
@@ -279,15 +309,15 @@ public class ManagedBeanResolver extends
     {
 
         final ExternalContext extContext = facesContext.getExternalContext();
-        final Map<String, Object> requestMap = extContext.getRequestMap();
+        final Map<Object, Object> facesContextMap = facesContext.getAttributes();
         final String managedBeanName = managedBean.getManagedBeanName();
 
         // check for cyclic references
-        List<String> beansUnderConstruction = (List<String>)requestMap.get(BEANS_UNDER_CONSTRUCTION);
+        List<String> beansUnderConstruction = (List<String>) facesContextMap.get(BEANS_UNDER_CONSTRUCTION);
         if (beansUnderConstruction == null)
         {
             beansUnderConstruction = new ArrayList<String>();
-            requestMap.put(BEANS_UNDER_CONSTRUCTION, beansUnderConstruction);
+            facesContextMap.put(BEANS_UNDER_CONSTRUCTION, beansUnderConstruction);
         }
         else if (beansUnderConstruction.contains(managedBeanName))
         {
@@ -338,9 +368,9 @@ public class ManagedBeanResolver extends
                 // managed-bean-scope could be a ValueExpression pointing to a Map (since 2.0)
                 // Optimisation: We do NOT check for cyclic references here, because when we reach this code,
                 // we have already checked for cyclic references in the custom scope
-                Object customScope = managedBean
-                                        .getManagedBeanScopeValueExpression(facesContext)
-                                            .getValue(facesContext.getELContext());
+                Object customScope = managedBean.getManagedBeanScopeValueExpression(facesContext)
+                        .getValue(facesContext.getELContext());
+                
                 if (customScope instanceof Map)
                 {
                     ((Map) customScope).put(managedBeanName, obj);
@@ -432,11 +462,12 @@ public class ManagedBeanResolver extends
     @Override
     public Class<?> getCommonPropertyType(final ELContext context, final Object base)
     {
+        if (base == null)
+        {
+            return Object.class;
+        }
 
-        if (base != null)
-            return null;
-
-        return Object.class;
+        return null;
     }
 
     interface Scope

Modified: myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/el/unified/resolver/ScopedAttributeResolver.java
URL: http://svn.apache.org/viewvc/myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/el/unified/resolver/ScopedAttributeResolver.java?rev=1097264&r1=1097263&r2=1097264&view=diff
==============================================================================
--- myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/el/unified/resolver/ScopedAttributeResolver.java (original)
+++ myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/el/unified/resolver/ScopedAttributeResolver.java Wed Apr 27 22:31:44 2011
@@ -18,11 +18,7 @@
  */
 package org.apache.myfaces.el.unified.resolver;
 
-import java.beans.FeatureDescriptor;
-import java.util.ArrayList;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
+import org.apache.myfaces.context.servlet.StartupServletExternalContextImpl;
 
 import javax.el.ELContext;
 import javax.el.ELException;
@@ -32,6 +28,11 @@ import javax.el.PropertyNotWritableExcep
 import javax.faces.component.UIViewRoot;
 import javax.faces.context.ExternalContext;
 import javax.faces.context.FacesContext;
+import java.beans.FeatureDescriptor;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
 
 /**
  * See JSF 1.2 spec section 5.6.2.7
@@ -182,33 +183,58 @@ public final class ScopedAttributeResolv
     private static Map<String, Object> findScopedMap(final FacesContext facesContext, final Object property)
     {
         if (facesContext == null)
+        {
             return null;
+        }
         
         final ExternalContext extContext = facesContext.getExternalContext();
         if (extContext == null)
+        {
             return null;
+        }
+
+        final boolean startup = (extContext instanceof StartupServletExternalContextImpl);
+        Map<String, Object> scopedMap;
+
+        // request scope (not available at startup)
+        if (!startup)
+        {
+            scopedMap = extContext.getRequestMap();
+            if (scopedMap.containsKey(property))
+            {
+                return scopedMap;
+            }
+        }
 
-        Map<String, Object> scopedMap = extContext.getRequestMap();
-        if (scopedMap.containsKey(property))
-            return scopedMap;
-        
         // jsf 2.0 view scope
         UIViewRoot root = facesContext.getViewRoot();
         if (root != null)
         {
             scopedMap = root.getViewMap(false);
             if (scopedMap != null && scopedMap.containsKey(property))
+            {
                 return scopedMap;
+            }
         }
 
-        scopedMap = extContext.getSessionMap();
-        if (scopedMap.containsKey(property))
-            return scopedMap;
+        // session scope (not available at startup)
+        if (!startup)
+        {
+            scopedMap = extContext.getSessionMap();
+            if (scopedMap.containsKey(property))
+            {
+                return scopedMap;
+            }
+        }
 
+        // application scope
         scopedMap = extContext.getApplicationMap();
         if (scopedMap.containsKey(property))
+        {
             return scopedMap;
+        }
 
+        // not found
         return null;
     }
 

Modified: myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/webapp/AbstractFacesInitializer.java
URL: http://svn.apache.org/viewvc/myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/webapp/AbstractFacesInitializer.java?rev=1097264&r1=1097263&r2=1097264&view=diff
==============================================================================
--- myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/webapp/AbstractFacesInitializer.java (original)
+++ myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/webapp/AbstractFacesInitializer.java Wed Apr 27 22:31:44 2011
@@ -30,7 +30,6 @@ import org.apache.myfaces.context.servle
 import org.apache.myfaces.shared_impl.context.ExceptionHandlerImpl;
 import org.apache.myfaces.shared_impl.util.StateUtils;
 import org.apache.myfaces.shared_impl.util.WebConfigParamUtils;
-import org.apache.myfaces.shared_impl.webapp.webxml.WebXml;
 import org.apache.myfaces.spi.WebConfigProvider;
 import org.apache.myfaces.spi.WebConfigProviderFactory;
 import org.apache.myfaces.view.facelets.tag.MetaRulesetImpl;
@@ -217,9 +216,16 @@ public abstract class AbstractFacesIniti
             
             for (ManagedBean bean : eagerBeans)
             {
+                // check application scope for bean instance
+                if (applicationMap.containsKey(bean.getManagedBeanName()))
+                {
+                    // do not build bean, because it already exists
+                    // (e.g. @ManagedProperty from previous managed bean already created it)
+                    continue;
+                }
+
                 // create instance
-                Object beanInstance = managedBeanBuilder
-                        .buildManagedBean(facesContext, bean);
+                Object beanInstance = managedBeanBuilder.buildManagedBean(facesContext, bean);
                 
                 // put in application scope
                 applicationMap.put(bean.getManagedBeanName(), beanInstance);