You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@myfaces.apache.org by lu...@apache.org on 2009/11/18 16:16:49 UTC
svn commit: r881798 - in /myfaces/core/trunk:
api/src/main/java/javax/faces/component/
impl/src/main/java/org/apache/myfaces/config/
impl/src/main/java/org/apache/myfaces/el/unified/resolver/
impl/src/test/java/org/apache/myfaces/config/ impl/src/test/...
Author: lu4242
Date: Wed Nov 18 15:16:45 2009
New Revision: 881798
URL: http://svn.apache.org/viewvc?rev=881798&view=rev
Log:
MYFACES-2399 ManagedBeanResolver does not handle view scope (Thanks to Jakob Korherr for this patch)
Modified:
myfaces/core/trunk/api/src/main/java/javax/faces/component/UIViewRoot.java
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/test/java/org/apache/myfaces/config/ManagedBeanBuilderTest.java
myfaces/core/trunk/impl/src/test/java/org/apache/myfaces/el/unified/resolver/ManagedBeanResolverTest.java
Modified: myfaces/core/trunk/api/src/main/java/javax/faces/component/UIViewRoot.java
URL: http://svn.apache.org/viewvc/myfaces/core/trunk/api/src/main/java/javax/faces/component/UIViewRoot.java?rev=881798&r1=881797&r2=881798&view=diff
==============================================================================
--- myfaces/core/trunk/api/src/main/java/javax/faces/component/UIViewRoot.java (original)
+++ myfaces/core/trunk/api/src/main/java/javax/faces/component/UIViewRoot.java Wed Nov 18 15:16:45 2009
@@ -1338,8 +1338,13 @@
}
}
- private class ViewScope extends HashMap<String, Object>
+ // we cannot make this class a inner class, because the
+ // enclosing class (UIViewRoot) would also have to be serialized.
+ private static class ViewScope extends HashMap<String, Object>
{
+
+ private static final long serialVersionUID = -1088893802269478164L;
+
@Override
public void clear()
{
@@ -1348,10 +1353,12 @@
* Application.publishEvent(java.lang.Class, java.lang.Object) to be called, passing
* ViewMapDestroyedEvent.class as the first argument and this UIViewRoot instance as the second argument.
*/
- FacesContext facesContext = getFacesContext();
- facesContext.getApplication().publishEvent(facesContext, PreDestroyViewMapEvent.class, UIViewRoot.this);
+ FacesContext facesContext = FacesContext.getCurrentInstance();
+ facesContext.getApplication().publishEvent(facesContext,
+ PreDestroyViewMapEvent.class, facesContext.getViewRoot());
super.clear();
}
+
}
}
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=881798&r1=881797&r2=881798&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 Nov 18 15:16:45 2009
@@ -67,13 +67,14 @@
private static Logger log = Logger.getLogger(ManagedBeanBuilder.class.getName());
private RuntimeConfig _runtimeConfig;
public final static String REQUEST = "request";
+ public final static String VIEW = "view";
public final static String APPLICATION = "application";
public final static String SESSION = "session";
public final static String NONE = "none";
/**
* Comparator used to compare Scopes in the following order:
- * REQUEST SESSION APPLICATION NONE
+ * REQUEST VIEW SESSION APPLICATION NONE
* @author Jakob Korherr
*/
private final static Comparator<String> scopeComparator = new Comparator<String>()
@@ -106,9 +107,9 @@
}
if (o1.equalsIgnoreCase(SESSION))
{
- if (o2.equalsIgnoreCase(REQUEST))
+ if (o2.equalsIgnoreCase(REQUEST) || o2.equalsIgnoreCase(VIEW))
{
- // session is greater than request
+ // session is greater than request and view
return 1;
}
else
@@ -117,6 +118,19 @@
return -1;
}
}
+ if (o1.equalsIgnoreCase(VIEW))
+ {
+ if (o2.equalsIgnoreCase(REQUEST))
+ {
+ // view is greater than request
+ return 1;
+ }
+ else
+ {
+ // ..but smaller than any other scope
+ return -1;
+ }
+ }
if (o1.equalsIgnoreCase(REQUEST))
{
// request is smaller than any other scope
@@ -394,6 +408,11 @@
beanConfiguration
.getManagedBeanScopeValueExpression(facesContext)
.getExpressionString());
+ // if we could not obtain a targetScope, return true
+ if (targetScope == null)
+ {
+ return true;
+ }
}
}
else
@@ -415,6 +434,12 @@
property.getValueBinding(facesContext)
.getExpressionString());
+ // if we could not obtain a valueScope, return true
+ if (valueScope == null)
+ {
+ return true;
+ }
+
// the target scope needs to have a shorter (or equal) lifetime than the value scope
return (scopeComparator.compare(targetScope, valueScope) <= 0);
}
@@ -428,7 +453,9 @@
private String getNarrowestScope(FacesContext facesContext, String valueExpression)
{
List<String> expressions = extractExpressions(valueExpression);
- String narrowestScope = NONE;
+ // exclude NONE scope, if there are more than one ValueExpressions (see Spec for details)
+ String narrowestScope = expressions.size() == 1 ? NONE : APPLICATION;
+ boolean scopeFound = false;
for (String expression : expressions)
{
@@ -437,13 +464,15 @@
{
continue;
}
+ // we have found at least one valid scope at this point
+ scopeFound = true;
if (scopeComparator.compare(valueScope, narrowestScope) < 0)
{
narrowestScope = valueScope;
}
}
- return narrowestScope;
+ return scopeFound ? narrowestScope : null;
}
private String getScope(FacesContext facesContext, String expression)
@@ -474,7 +503,6 @@
{
return REQUEST;
}
-
if (beanName.equalsIgnoreCase("header"))
{
return REQUEST;
@@ -483,11 +511,6 @@
{
return REQUEST;
}
-
- if (beanName.equalsIgnoreCase("initParam"))
- {
- return APPLICATION;
- }
if (beanName.equalsIgnoreCase("param"))
{
return REQUEST;
@@ -496,10 +519,22 @@
{
return REQUEST;
}
- if (beanName.equalsIgnoreCase("view"))
+ if (beanName.equalsIgnoreCase("request"))
{
return REQUEST;
}
+ if (beanName.equalsIgnoreCase("view")) // Spec says that view is considered to be in request scope
+ {
+ return REQUEST;
+ }
+ if (beanName.equalsIgnoreCase("application"))
+ {
+ return APPLICATION;
+ }
+ if (beanName.equalsIgnoreCase("initParam"))
+ {
+ return APPLICATION;
+ }
// not found so far - check all scopes
if (externalContext.getRequestMap().get(beanName) != null)
@@ -514,6 +549,10 @@
{
return APPLICATION;
}
+ if (facesContext.getViewRoot().getViewMap().get(beanName) != null)
+ {
+ return VIEW;
+ }
//not found - check mangaged bean config
@@ -530,8 +569,7 @@
// However, we do check the references, if we are not in Production stage
if (facesContext.getApplication().getProjectStage() == ProjectStage.Production)
{
- // we return NONE, because the NONE scope can be referenced by any other scope
- return NONE;
+ return null;
}
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=881798&r1=881797&r2=881798&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 Nov 18 15:16:45 2009
@@ -62,7 +62,7 @@
{
s_standardScopes.put("request", new Scope()
{
- public void put(ExternalContext extContext, String name, Object obj)
+ public void put(FacesContext facesContext, ExternalContext extContext, String name, Object obj)
{
extContext.getRequestMap().put(name, obj);
}
@@ -70,7 +70,7 @@
s_standardScopes.put("session", new Scope()
{
- public void put(ExternalContext extContext, String name, Object obj)
+ public void put(FacesContext facesContext, ExternalContext extContext, String name, Object obj)
{
extContext.getSessionMap().put(name, obj);
}
@@ -78,7 +78,7 @@
s_standardScopes.put("application", new Scope()
{
- public void put(ExternalContext extContext, String name, Object obj)
+ public void put(FacesContext facesContext, ExternalContext extContext, String name, Object obj)
{
extContext.getApplicationMap().put(name, obj);
}
@@ -86,11 +86,20 @@
s_standardScopes.put("none", new Scope()
{
- public void put(ExternalContext extContext, String name, Object obj)
+ public void put(FacesContext facesContext, ExternalContext extContext, String name, Object obj)
{
// do nothing
}
});
+
+ // jsf 2.0 view scope
+ s_standardScopes.put("view", new Scope()
+ {
+ public void put(FacesContext facesContext, ExternalContext extContext, String name, Object obj)
+ {
+ facesContext.getViewRoot().getViewMap().put(name, obj);
+ }
+ });
}
/**
@@ -161,12 +170,19 @@
throw new PropertyNotFoundException();
}
- final ExternalContext extContext = externalContext(context);
-
+ final FacesContext facesContext = facesContext(context);
+ if (facesContext == null)
+ return null;
+
+ final ExternalContext extContext = facesContext.getExternalContext();
if (extContext == null)
return null;
+
if (extContext.getRequestMap().containsKey(property))
return null;
+ Map<String, Object> viewMap = facesContext.getViewRoot().getViewMap(false);
+ if (viewMap != null && viewMap.containsKey(property))
+ return null;
if (extContext.getSessionMap().containsKey(property))
return null;
if (extContext.getApplicationMap().containsKey(property))
@@ -181,7 +197,6 @@
Object beanInstance = null;
if (managedBean != null)
{
- FacesContext facesContext = facesContext(context);
context.setPropertyResolved(true);
// managed-bean-scope could be a ValueExpression pointing to a Map (since 2.0)
@@ -311,7 +326,7 @@
final Scope scope = _scopes.get(scopeKey);
if (scope != null)
{
- scope.put(extContext, managedBeanName, obj);
+ scope.put(facesContext, extContext, managedBeanName, obj);
}
else if (managedBean.isManagedBeanScopeValueExpression())
{
@@ -428,6 +443,6 @@
interface Scope
{
- public void put(ExternalContext extContext, String name, Object obj);
+ public void put(FacesContext facesContext, ExternalContext extContext, String name, Object obj);
}
}
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=881798&r1=881797&r2=881798&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 Nov 18 15:16:45 2009
@@ -61,7 +61,7 @@
throw new PropertyNotFoundException();
}
- final Map<String, Object> scopedMap = findScopedMap(externalContext(context), property);
+ final Map<String, Object> scopedMap = findScopedMap(facesContext(context), property);
if (scopedMap != null)
{
scopedMap.put((String)property, value);
@@ -102,7 +102,7 @@
context.setPropertyResolved(true);
- final Map<String, Object> scopedMap = findScopedMap(externalContext(context), property);
+ final Map<String, Object> scopedMap = findScopedMap(facesContext(context), property);
if (scopedMap != null)
{
return scopedMap.get(property);
@@ -178,14 +178,23 @@
}
// returns null if not found
- private static Map<String, Object> findScopedMap(final ExternalContext extContext, final Object property)
+ 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;
Map<String, Object> scopedMap = extContext.getRequestMap();
if (scopedMap.containsKey(property))
return scopedMap;
+
+ // jsf 2.0 view scope
+ scopedMap = facesContext.getViewRoot().getViewMap(false);
+ if (scopedMap != null && scopedMap.containsKey(property))
+ return scopedMap;
scopedMap = extContext.getSessionMap();
if (scopedMap.containsKey(property))
Modified: myfaces/core/trunk/impl/src/test/java/org/apache/myfaces/config/ManagedBeanBuilderTest.java
URL: http://svn.apache.org/viewvc/myfaces/core/trunk/impl/src/test/java/org/apache/myfaces/config/ManagedBeanBuilderTest.java?rev=881798&r1=881797&r2=881798&view=diff
==============================================================================
--- myfaces/core/trunk/impl/src/test/java/org/apache/myfaces/config/ManagedBeanBuilderTest.java (original)
+++ myfaces/core/trunk/impl/src/test/java/org/apache/myfaces/config/ManagedBeanBuilderTest.java Wed Nov 18 15:16:45 2009
@@ -195,5 +195,44 @@
}
fail();
}
+
+ /**
+ * Tests, if the ManagedBeanBuilder checks that no property of the managed bean
+ * references to a scope with a potentially shorter lifetime.
+ * E.g. a managed bean of scope session is only allowed to reference an object in
+ * the session, the application and the none scope.
+ * This test is to test the view scope, introduced in jsf 2.0.
+ */
+ public void testIsInValidScopeViewScope()
+ {
+ // create viewBean referencing requestBean
+ ManagedBean viewBean = new ManagedBean();
+ viewBean.setBeanClass(TestBean.class.getName());
+ viewBean.setName("viewBean");
+ viewBean.setScope("view");
+ ManagedProperty anotherBeanProperty = new ManagedProperty();
+ anotherBeanProperty.setPropertyName("anotherBean");
+ anotherBeanProperty.setValue("#{requestBean}");
+ viewBean.addProperty(anotherBeanProperty);
+ runtimeConfig.addManagedBean("viewBean", viewBean);
+
+ // create requestBean
+ ManagedBean requestBean = new ManagedBean();
+ requestBean.setBeanClass(TestBean.class.getName());
+ requestBean.setName("requestBean");
+ requestBean.setScope("request");
+ runtimeConfig.addManagedBean("requestBean", requestBean);
+
+ try
+ {
+ new MockValueExpression("#{viewBean}", TestBean.class).getValue(facesContext.getELContext());
+ }
+ catch (FacesException e)
+ {
+ // success --> the ManagedBeanBuilder discovered the reference to a shorter lifetime
+ return;
+ }
+ fail();
+ }
}
Modified: myfaces/core/trunk/impl/src/test/java/org/apache/myfaces/el/unified/resolver/ManagedBeanResolverTest.java
URL: http://svn.apache.org/viewvc/myfaces/core/trunk/impl/src/test/java/org/apache/myfaces/el/unified/resolver/ManagedBeanResolverTest.java?rev=881798&r1=881797&r2=881798&view=diff
==============================================================================
--- myfaces/core/trunk/impl/src/test/java/org/apache/myfaces/el/unified/resolver/ManagedBeanResolverTest.java (original)
+++ myfaces/core/trunk/impl/src/test/java/org/apache/myfaces/el/unified/resolver/ManagedBeanResolverTest.java Wed Nov 18 15:16:45 2009
@@ -215,5 +215,29 @@
}
fail();
}
+
+ /**
+ * Tests the view scope, which was introduced in jsf 2.0
+ */
+ public void testViewScope()
+ {
+ // create the managed bean
+ ManagedBean beanInViewScope = new ManagedBean();
+ beanInViewScope.setBeanClass(ArrayList.class.getName());
+ beanInViewScope.setName("beanInViewScope");
+ beanInViewScope.setScope("view");
+ runtimeConfig.addManagedBean("beanInViewScope", beanInViewScope);
+
+ // resolve the managed bean
+ Object resolvedBeanInCustomScope = new MockValueExpression("#{beanInViewScope}", List.class)
+ .getValue(facesContext.getELContext());
+
+ // get the view map
+ Map<String, Object> viewMap = facesContext.getViewRoot().getViewMap();
+
+ // the custom scope has to contain the resolved bean
+ assertTrue(viewMap.containsKey("beanInViewScope"));
+ assertTrue(viewMap.get("beanInViewScope").equals(resolvedBeanInCustomScope));
+ }
}