You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@myfaces.apache.org by or...@apache.org on 2005/09/10 14:38:02 UTC

svn commit: r279999 - in /myfaces/impl/trunk/src/java/org/apache/myfaces/config: ManagedBeanBuilder.java element/ManagedProperty.java impl/digester/elements/ManagedProperty.java

Author: oros
Date: Sat Sep 10 05:37:54 2005
New Revision: 279999

URL: http://svn.apache.org/viewcvs?rev=279999&view=rev
Log:
MYFACES-523: check scope of referenced beans

Modified:
    myfaces/impl/trunk/src/java/org/apache/myfaces/config/ManagedBeanBuilder.java
    myfaces/impl/trunk/src/java/org/apache/myfaces/config/element/ManagedProperty.java
    myfaces/impl/trunk/src/java/org/apache/myfaces/config/impl/digester/elements/ManagedProperty.java

Modified: myfaces/impl/trunk/src/java/org/apache/myfaces/config/ManagedBeanBuilder.java
URL: http://svn.apache.org/viewcvs/myfaces/impl/trunk/src/java/org/apache/myfaces/config/ManagedBeanBuilder.java?rev=279999&r1=279998&r2=279999&view=diff
==============================================================================
--- myfaces/impl/trunk/src/java/org/apache/myfaces/config/ManagedBeanBuilder.java (original)
+++ myfaces/impl/trunk/src/java/org/apache/myfaces/config/ManagedBeanBuilder.java Sat Sep 10 05:37:54 2005
@@ -23,8 +23,10 @@
 import javax.faces.FacesException;
 import javax.faces.application.Application;
 import javax.faces.context.FacesContext;
+import javax.faces.context.ExternalContext;
 import javax.faces.el.PropertyResolver;
 import javax.faces.el.ValueBinding;
+import javax.faces.el.EvaluationException;
 import javax.faces.webapp.UIComponentTag;
 import java.util.*;
 import java.lang.reflect.Array;
@@ -39,6 +41,8 @@
 public class ManagedBeanBuilder
 {
     private static Log log = LogFactory.getLog(ManagedBeanBuilder.class);
+    private RuntimeConfig _runtimeConfig;
+
 
     public Object buildManagedBean(FacesContext facesContext, ManagedBean beanConfiguration) throws FacesException
     {
@@ -48,8 +52,8 @@
         {
             case ManagedBean.INIT_MODE_PROPERTIES:
                 try {
-                  initializeProperties(facesContext, beanConfiguration
-                      .getManagedProperties(), bean);
+                  initializeProperties(facesContext, beanConfiguration.getManagedProperties(),
+                      beanConfiguration.getManagedBeanScope(), bean);
                 } catch (IllegalArgumentException e) {
                   throw new IllegalArgumentException(
                           e.getMessage()
@@ -94,7 +98,7 @@
     }
 
 
-    private void initializeProperties(FacesContext facesContext, Iterator managedProperties, Object bean)
+    private void initializeProperties(FacesContext facesContext, Iterator managedProperties, String targetScope, Object bean)
     {
         PropertyResolver propertyResolver =
             facesContext.getApplication().getPropertyResolver();
@@ -145,6 +149,11 @@
                     value = null;
                     break;
                 case ManagedProperty.TYPE_VALUE:
+                    // check for correct scope of a referenced bean
+                    if (! isInValidScope(facesContext, property, targetScope)) {
+                        throw new FacesException("Property " + property.getPropertyName() +
+                            " references object in a scope with shorter lifetime than the target scope " + targetScope);
+                    }
                     value = property.getRuntimeValue(facesContext);
                     break;
             }
@@ -170,6 +179,219 @@
     }
 
 
+    /**
+     * Check if the scope of the property value is valid for a bean to be stored in targetScope.
+     * @param facesContext
+     * @param property          the property to be checked
+     * @param targetScope       name of the target scope of the bean under construction
+     */
+    private boolean isInValidScope(FacesContext facesContext, ManagedProperty property, String targetScope)
+    {
+        if (! property.isValueReference()) {
+            // no value reference but a literal value -> nothing to check
+            return true;
+        }
+        String[] expressions = extractExpressions(property.getValueBinding(facesContext).getExpressionString());
+
+        for (int i = 0; i < expressions.length; i++) {
+            String expression = expressions[i];
+            if (expression == null) {
+                continue;
+            }
+
+            String valueScope = getScope(facesContext, expression);
+
+            // if the target scope is 'none' value scope has to be 'none', too
+            if (targetScope == null || targetScope.equalsIgnoreCase("none")) {
+                if (valueScope != null && !(valueScope.equalsIgnoreCase("none"))) {
+                    return false;
+                }
+                return true;
+            }
+
+            // 'application' scope can reference 'application' and 'none'
+            if (targetScope.equalsIgnoreCase("application")) {
+                if (valueScope != null) {
+                    if (valueScope.equalsIgnoreCase("request") ||
+                        valueScope.equalsIgnoreCase("session")) {
+                        return false;
+                    }
+                }
+                return true;
+            }
+
+            // 'session' scope can reference 'session', 'application', and 'none' but not 'request'
+            if (targetScope.equalsIgnoreCase("session")) {
+                if (valueScope != null) {
+                    if (valueScope.equalsIgnoreCase("request")) {
+                        return false;
+                    }
+                }
+                return true;
+            }
+
+            // 'request' scope can reference any value scope
+            if (targetScope.equalsIgnoreCase("request")) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+
+    private String getScope(FacesContext facesContext, String expression)
+    {
+        String beanName = getFirstSegment(expression);
+        ExternalContext externalContext = facesContext.getExternalContext();
+
+        // check scope objects
+        if (beanName.equalsIgnoreCase("requestScope")) {
+            return "request";
+        }
+        if (beanName.equalsIgnoreCase("sessionScope")) {
+            return "session";
+        }
+        if (beanName.equalsIgnoreCase("applicationScope")) {
+            return "application";
+        }
+
+	    // check implicit objects
+        if (beanName.equalsIgnoreCase("cookie")) {
+	    return "request";
+        }
+        if (beanName.equalsIgnoreCase("facesContext")) {
+            return "request";
+        }
+
+        if (beanName.equalsIgnoreCase("header")) {
+            return "request";
+        }
+        if (beanName.equalsIgnoreCase("headerValues")) {
+            return "request";
+        }
+
+        if (beanName.equalsIgnoreCase("initParam")) {
+	    return "application";
+        }
+        if (beanName.equalsIgnoreCase("param")) {
+            return "request";
+        }
+        if (beanName.equalsIgnoreCase("paramValues")) {
+            return "request";
+        }
+        if (beanName.equalsIgnoreCase("view")) {
+            return "request";
+        }
+
+
+        // not found so far - check all scopes
+        if (externalContext.getRequestMap().get(beanName) != null) {
+            return "request";
+        }
+        if (externalContext.getSessionMap().get(beanName) != null) {
+            return "session";
+        }
+        if (externalContext.getApplicationMap().get(beanName) != null) {
+            return "application";
+        }
+
+        //not found - check mangaged bean config
+
+
+        ManagedBean mbc = getRuntimeConfig(facesContext).getManagedBean(beanName);
+
+        if (mbc != null) {
+            return mbc.getManagedBeanScope();
+        }
+
+        return null;
+    }
+
+
+
+
+    /**
+     * Extract the first expression segment, that is the substring up to the first '.' or '['
+     * @param expression
+     * @return first segment of the expression
+     */
+    private String getFirstSegment(String expression)
+    {
+        int indexDot = expression.indexOf('.');
+        int indexBracket = expression.indexOf('[');
+
+        if (indexBracket < 0) {
+                if (indexDot < 0) {
+                    return expression;
+                } else {
+                    return expression.substring(0, indexDot);
+                }
+        } else {
+            if (indexDot < 0) {
+                return expression.substring(0, indexBracket);
+            } else {
+                return expression.substring(0, Math.min(indexDot, indexBracket));
+            }
+        }
+    }
+
+    private String getSecondSegment(String expression, String firstSegment)
+    {
+        String tmp = expression.substring(firstSegment.length());
+
+        if (tmp.length() == 0) {
+            return null;
+        }
+        if (tmp.charAt(0) == '.') {
+            return getFirstSegment(tmp.substring(1));
+        }
+        // starts with [
+        tmp = tmp.substring(1).trim();
+        int index;
+
+        if (tmp.charAt(0) == '"') {
+            index = tmp.indexOf('"', 1);
+
+            if (index < 0) {
+                throw new EvaluationException(tmp);
+            }
+            return tmp.substring(1, index);
+        }
+        if (tmp.charAt(0) == '\'') {
+            index = tmp.indexOf('\'', 1);
+
+            if (index < 0) {
+                throw new EvaluationException(tmp);
+            }
+            return tmp.substring(1, index);
+        }
+
+        index = tmp.indexOf(']');
+
+        if (index < 0) {
+            throw new EvaluationException(tmp);
+        }
+
+        return tmp.substring(1, index);
+    }
+
+
+    private String[] extractExpressions(String expressionString)
+    {
+        String[] expressions = expressionString.split("\\#\\{");
+        for (int i = 0; i < expressions.length; i++) {
+            String expression = expressions[i];
+            if (expression.trim().length() == 0) {
+                expressions[i] = null;
+            } else {
+                int index = expression.indexOf('}');
+                expressions[i] = expression.substring(0, index);
+            }
+        }
+        return expressions;
+    }
+
+
     private void initializeMap(FacesContext facesContext, MapEntries mapEntries, Map map)
     {
         Application application = facesContext.getApplication();
@@ -232,5 +454,14 @@
                 list.add(ClassUtils.convertToType(value, valueClass));
             }
         }
+    }
+
+    private RuntimeConfig getRuntimeConfig(FacesContext facesContext)
+    {
+        if (_runtimeConfig == null)
+        {
+            _runtimeConfig = RuntimeConfig.getCurrentInstance(facesContext.getExternalContext());
+        }
+        return _runtimeConfig;
     }
 }

Modified: myfaces/impl/trunk/src/java/org/apache/myfaces/config/element/ManagedProperty.java
URL: http://svn.apache.org/viewcvs/myfaces/impl/trunk/src/java/org/apache/myfaces/config/element/ManagedProperty.java?rev=279999&r1=279998&r2=279999&view=diff
==============================================================================
--- myfaces/impl/trunk/src/java/org/apache/myfaces/config/element/ManagedProperty.java (original)
+++ myfaces/impl/trunk/src/java/org/apache/myfaces/config/element/ManagedProperty.java Sat Sep 10 05:37:54 2005
@@ -16,6 +16,7 @@
 package org.apache.myfaces.config.element;
 
 import javax.faces.context.FacesContext;
+import javax.faces.el.ValueBinding;
 
 import org.apache.myfaces.config.element.ListEntries;
 
@@ -43,4 +44,6 @@
     public MapEntries getMapEntries();
     public ListEntries getListEntries();
     public Object getRuntimeValue(FacesContext facesContext);
+    public boolean isValueReference();
+    public ValueBinding getValueBinding(FacesContext facesContext);
 }

Modified: myfaces/impl/trunk/src/java/org/apache/myfaces/config/impl/digester/elements/ManagedProperty.java
URL: http://svn.apache.org/viewcvs/myfaces/impl/trunk/src/java/org/apache/myfaces/config/impl/digester/elements/ManagedProperty.java?rev=279999&r1=279998&r2=279999&view=diff
==============================================================================
--- myfaces/impl/trunk/src/java/org/apache/myfaces/config/impl/digester/elements/ManagedProperty.java (original)
+++ myfaces/impl/trunk/src/java/org/apache/myfaces/config/impl/digester/elements/ManagedProperty.java Sat Sep 10 05:37:54 2005
@@ -117,16 +117,29 @@
 
     public Object getRuntimeValue(FacesContext facesContext)
     {
+        getValueBinding(facesContext);
+
+        return (_valueBinding == DUMMY_VB)
+            ? _value : _valueBinding.getValue(facesContext);
+    }
+
+
+    public ValueBinding getValueBinding(FacesContext facesContext)
+    {
         if (_valueBinding == null)
         {
             _valueBinding =
-                UIComponentTag.isValueReference(_value)
+                isValueReference()
                 ? facesContext.getApplication().createValueBinding(_value)
                 : DUMMY_VB;
         }
+        return _valueBinding;
+    }
 
-        return (_valueBinding == DUMMY_VB)
-            ? _value : _valueBinding.getValue(facesContext);
+
+    public boolean isValueReference()
+    {
+        return UIComponentTag.isValueReference(_value);
     }