You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@shale.apache.org by cr...@apache.org on 2006/10/08 01:34:52 UTC

svn commit: r454044 - in /shale/framework/trunk/shale-test/src/main/java/org/apache/shale/test: el/ mock/

Author: craigmcc
Date: Sat Oct  7 16:34:51 2006
New Revision: 454044

URL: http://svn.apache.org/viewvc?view=rev&rev=454044
Log:
Add more infrastructure for test time expression evaluation using JSF 1.2
(and the Unified EL) APIs.  the org.apache.shale.test.el package contains
implementations of ELResolver that behave as specified in Chapter 5 of the
JSF 1.2 Specification.

SHALE-304


Added:
    shale/framework/trunk/shale-test/src/main/java/org/apache/shale/test/el/
    shale/framework/trunk/shale-test/src/main/java/org/apache/shale/test/el/AbstractELResolver.java
    shale/framework/trunk/shale-test/src/main/java/org/apache/shale/test/el/FacesImplicitObjectELResolver.java
    shale/framework/trunk/shale-test/src/main/java/org/apache/shale/test/el/FacesPropertyResolverChainWrapper.java
    shale/framework/trunk/shale-test/src/main/java/org/apache/shale/test/el/FacesResourceBundleELResolver.java
    shale/framework/trunk/shale-test/src/main/java/org/apache/shale/test/el/FacesScopedAttributeELResolver.java
    shale/framework/trunk/shale-test/src/main/java/org/apache/shale/test/el/FacesVariableResolverChainWrapper.java
Modified:
    shale/framework/trunk/shale-test/src/main/java/org/apache/shale/test/mock/MockApplication12.java

Added: shale/framework/trunk/shale-test/src/main/java/org/apache/shale/test/el/AbstractELResolver.java
URL: http://svn.apache.org/viewvc/shale/framework/trunk/shale-test/src/main/java/org/apache/shale/test/el/AbstractELResolver.java?view=auto&rev=454044
==============================================================================
--- shale/framework/trunk/shale-test/src/main/java/org/apache/shale/test/el/AbstractELResolver.java (added)
+++ shale/framework/trunk/shale-test/src/main/java/org/apache/shale/test/el/AbstractELResolver.java Sat Oct  7 16:34:51 2006
@@ -0,0 +1,70 @@
+/*
+ * Copyright 2006 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.shale.test.el;
+
+import java.beans.FeatureDescriptor;
+import javax.el.ELResolver;
+
+/**
+ * <p>Convenience base class for EL resolvers.</p>
+ */
+abstract class AbstractELResolver extends ELResolver {
+    
+
+
+    // ------------------------------------------------------- Protected Methods
+
+
+    /**
+     * <p>Create and return a <code>FeatureDescriptor</code> configured with
+     * the specified arguments.</p>
+     *
+     * @param name Feature name
+     * @param displayName Display name
+     * @param description Short description
+     * @param expert Flag indicating this feature is for experts
+     * @param hidden Flag indicating this feature should be hidden
+     * @param preferred Flag indicating this feature is the preferred one
+     *  among features of the same type
+     * @param type Runtime type of this feature
+     * @param designTime Flag indicating feature is resolvable at design time
+     */
+    protected FeatureDescriptor descriptor(String name, String displayName,
+      String description, boolean expert, boolean hidden, boolean preferred,
+      Object type, boolean designTime) {
+
+      FeatureDescriptor descriptor = new FeatureDescriptor();
+
+      descriptor.setName(name);
+      descriptor.setDisplayName(displayName);
+      descriptor.setShortDescription(description);
+      descriptor.setExpert(expert);
+      descriptor.setHidden(hidden);
+      descriptor.setPreferred(preferred);
+      descriptor.setValue(ELResolver.TYPE, type);
+      if (designTime) {
+          descriptor.setValue(ELResolver.RESOLVABLE_AT_DESIGN_TIME, Boolean.TRUE);
+      } else {
+          descriptor.setValue(ELResolver.RESOLVABLE_AT_DESIGN_TIME, Boolean.FALSE);
+      }
+
+      return descriptor;
+
+    }
+
+
+}

Added: shale/framework/trunk/shale-test/src/main/java/org/apache/shale/test/el/FacesImplicitObjectELResolver.java
URL: http://svn.apache.org/viewvc/shale/framework/trunk/shale-test/src/main/java/org/apache/shale/test/el/FacesImplicitObjectELResolver.java?view=auto&rev=454044
==============================================================================
--- shale/framework/trunk/shale-test/src/main/java/org/apache/shale/test/el/FacesImplicitObjectELResolver.java (added)
+++ shale/framework/trunk/shale-test/src/main/java/org/apache/shale/test/el/FacesImplicitObjectELResolver.java Sat Oct  7 16:34:51 2006
@@ -0,0 +1,274 @@
+/*
+ * Copyright 2006 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.shale.test.el;
+
+import java.beans.FeatureDescriptor;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Set;
+import javax.el.ELContext;
+import javax.el.ELResolver;
+import javax.el.PropertyNotFoundException;
+import javax.el.PropertyNotWritableException;
+import javax.faces.component.UIViewRoot;
+import javax.faces.context.ExternalContext;
+import javax.faces.context.FacesContext;
+
+/**
+ * <p><code>ELResolver</code> implementation that accesses implicit objects
+ * in the current request context.  See the JSF 1.2 Specification, section
+ * 5.6.2.1, for requirements implemented by this class.</p>
+ *
+ * @since 1.0.4
+ */
+public class FacesImplicitObjectELResolver extends AbstractELResolver {
+    
+
+    /**
+     * <p>The names of all implicit objects recognized by this resolver.</p>
+     */
+    private static final String[] NAMES =
+    { "application", "applicationScope", "cookie", "facesContext",
+      "header", "headerValues", "initParam", "param", "paramValues",
+      "request", "requestScope", "session", "sessionScope", "view" };
+
+
+    /**
+     * <p>The property types corresponding to the implicit object names.</p>
+     */
+    private static final Class[] TYPES =
+    { Object.class, Map.class, Map.class, FacesContext.class,
+      Map.class, Map.class, Map.class, Map.class, Map.class,
+      Object.class, Map.class, Object.class, Map.class, UIViewRoot.class };
+
+
+    /**
+     * <p>The settable value types corresponding to the implicit
+     * object names.</p>
+     */
+    private static final Class[] VALUES =
+    { null, Object.class, null, null,
+      null, null, null, null, null,
+      null, Object.class, null, Object.class, null };
+
+
+    /**
+     * <p>Return the most general type this resolver accepts for the
+     * <code>property</code> argument.</p>
+     */
+    public Class getCommonPropertyType(ELContext context, Object base) {
+
+        if (base != null) {
+            return null;
+        } else {
+            return String.class;
+        }
+
+    }
+
+
+    /**
+     * <p>Return an <code>Iterator</code> over the attributes that this
+     * resolver knows how to deal with.</p>
+     *
+     * @param context <code>ELContext</code> for evaluating this value
+     * @param base Base object against which this evaluation occurs
+     */
+    public Iterator getFeatureDescriptors(ELContext context, Object base) {
+
+        if (base != null) {
+            return null;
+        }
+
+        // Create the variables we will need
+        FacesContext fcontext = (FacesContext) context.getContext(FacesContext.class);
+        List descriptors = new ArrayList();
+
+        // Add feature descriptors for each implicit object
+        for (int i = 0; i < NAMES.length; i++) {
+            descriptors.add(descriptor(NAMES[i], NAMES[i], NAMES[i],
+                                   false, false, true, TYPES[i], true));
+        }
+
+        // Return the accumulated descriptors
+        return descriptors.iterator();
+
+    }
+
+
+
+    /**
+     * <p>Return the Java type of the specified property.</p>
+     *
+     * @param context <code>ELContext</code> for evaluating this value
+     * @param base Base object against which this evaluation occurs
+     *  (must be null because we are evaluating a top level variable)
+     * @param property Property name to be accessed
+     */
+    public Class getType(ELContext context, Object base, Object property) {
+
+        if (base != null) {
+            return null;
+        }
+        if (property == null) {
+            throw new PropertyNotFoundException("No property specified");
+        }
+        String name = property.toString();
+        for (int i = 0; i < NAMES.length; i++) {
+            if (name.equals(NAMES[i])) {
+                context.setPropertyResolved(true);
+                return VALUES[i];
+            }
+        }
+        return null;
+
+    }
+
+
+    /**
+     * <p>Return an existing scoped object for the specified name (if any);
+     * otherwise, return <code>null</code>.</p>
+     *
+     * @param context <code>ELContext</code> for evaluating this value
+     * @param base Base object against which this evaluation occurs
+     *  (must be null because we are evaluating a top level variable)
+     * @param property Property name to be accessed
+     */
+    public Object getValue(ELContext context, Object base, Object property) {
+
+        if (base != null) {
+            return null;
+        }
+        if (property == null) {
+            throw new PropertyNotFoundException("No property specified");
+        }
+
+        FacesContext fcontext = (FacesContext) context.getContext(FacesContext.class);
+        ExternalContext econtext = fcontext.getExternalContext();
+        String name = property.toString();
+
+        if (name.equals("application")) {
+            context.setPropertyResolved(true);
+            return econtext.getContext();
+        } else if (name.equals("applicationScope")) {
+            context.setPropertyResolved(true);
+            return econtext.getApplicationMap();
+        } else if (name.equals("cookie")) {
+            context.setPropertyResolved(true);
+            return econtext.getRequestCookieMap();
+        } else if (name.equals("facesContext")) {
+            context.setPropertyResolved(true);
+            return fcontext;
+        } else if (name.equals("header")) {
+            context.setPropertyResolved(true);
+            return econtext.getRequestHeaderMap();
+        } else if (name.equals("headerValues")) {
+            context.setPropertyResolved(true);
+            return econtext.getRequestHeaderValuesMap();
+        } else if (name.equals("initParam")) {
+            context.setPropertyResolved(true);
+            return econtext.getInitParameterMap();
+        } else if (name.equals("param")) {
+            context.setPropertyResolved(true);
+            return econtext.getRequestParameterMap();
+        } else if (name.equals("paramValues")) {
+            context.setPropertyResolved(true);
+            return econtext.getRequestParameterValuesMap();
+        } else if (name.equals("request")) {
+            context.setPropertyResolved(true);
+            return econtext.getRequest();
+        } else if (name.equals("requestScope")) {
+            context.setPropertyResolved(true);
+            return econtext.getRequestMap();
+        } else if (name.equals("session")) {
+            context.setPropertyResolved(true);
+            return econtext.getSession(true);
+        } else if (name.equals("sessionScope")) {
+            context.setPropertyResolved(true);
+            return econtext.getSessionMap();
+        } else if (name.equals("view")) {
+            context.setPropertyResolved(true);
+            return fcontext.getViewRoot();
+        }
+
+        return null;
+
+    }
+
+
+    /**
+     * <p>Return <code>true</code> if the specified property is read only.</p>
+     *
+     * @param context <code>ELContext</code> for evaluating this value
+     * @param base Base object against which this evaluation occurs
+     *  (must be null because we are evaluating a top level variable)
+     * @param property Property name to be accessed
+     */
+    public boolean isReadOnly(ELContext context, Object base, Object property) {
+
+        if (base != null) {
+            return false;
+        }
+        if (property == null) {
+            throw new PropertyNotFoundException("No property specified");
+        }
+        String name = property.toString();
+        for (int i = 0; i < NAMES.length; i++) {
+            if (name.equals(NAMES[i])) {
+                context.setPropertyResolved(true);
+                return true;
+            }
+        }
+        return false;
+
+    }
+
+
+
+    /**
+     * <p>Set the value of a scoped object for the specified name.</p>
+     *
+     * @param context <code>ELContext</code> for evaluating this value
+     * @param base Base object against which this evaluation occurs
+     *  (must be null because we are evaluating a top level variable)
+     * @param property Property name to be accessed
+     * @param value New value to be set
+     */
+    public void setValue(ELContext context, Object base, Object property, Object value) {
+
+        if (base != null) {
+            return;
+        }
+        if (property == null) {
+            throw new PropertyNotFoundException("No property specified");
+        }
+
+        String name = property.toString();
+        for (int i = 0; i < NAMES.length; i++) {
+            if (name.equals(NAMES[i])) {
+                context.setPropertyResolved(true);
+                throw new PropertyNotWritableException(name);
+            }
+        }
+
+    }
+
+
+}

Added: shale/framework/trunk/shale-test/src/main/java/org/apache/shale/test/el/FacesPropertyResolverChainWrapper.java
URL: http://svn.apache.org/viewvc/shale/framework/trunk/shale-test/src/main/java/org/apache/shale/test/el/FacesPropertyResolverChainWrapper.java?view=auto&rev=454044
==============================================================================
--- shale/framework/trunk/shale-test/src/main/java/org/apache/shale/test/el/FacesPropertyResolverChainWrapper.java (added)
+++ shale/framework/trunk/shale-test/src/main/java/org/apache/shale/test/el/FacesPropertyResolverChainWrapper.java Sat Oct  7 16:34:51 2006
@@ -0,0 +1,241 @@
+/*
+ * Copyright 2006 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.shale.test.el;
+
+import java.beans.FeatureDescriptor;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Set;
+import javax.el.ELContext;
+import javax.el.ELException;
+import javax.el.ELResolver;
+import javax.el.PropertyNotFoundException;
+import javax.el.PropertyNotWritableException;
+import javax.faces.component.UIViewRoot;
+import javax.faces.context.ExternalContext;
+import javax.faces.context.FacesContext;
+import javax.faces.el.EvaluationException;
+import javax.faces.el.PropertyResolver;
+
+/**
+ * <p><code>ELResolver</code> implementation that wraps the legacy (JSF 1.1)
+ * <code>PropertyResolver</code> chain.  See the JSF 1.2 Specification, section
+ * 5.6.1.6, for requirements implemented by this class.</p>
+ *
+ * @since 1.0.4
+ */
+public class FacesPropertyResolverChainWrapper extends AbstractELResolver {
+    
+
+    /**
+     * <p>Return the most general type this resolver accepts for the
+     * <code>property</code> argument.</p>
+     */
+    public Class getCommonPropertyType(ELContext context, Object base) {
+
+        if (base != null) {
+            return null;
+        } else {
+            return Object.class;
+        }
+
+    }
+
+
+    /**
+     * <p>Return an <code>Iterator</code> over the attributes that this
+     * resolver knows how to deal with.</p>
+     *
+     * @param context <code>ELContext</code> for evaluating this value
+     * @param base Base object against which this evaluation occurs
+     */
+    public Iterator getFeatureDescriptors(ELContext context, Object base) {
+
+        return null;
+
+    }
+
+
+
+    /**
+     * <p>Evaluate with the legacy property resolver chain and return
+     * the value.</p>
+     *
+     * @param context <code>ELContext</code> for evaluating this value
+     * @param base Base object against which this evaluation occurs
+     *  (must be null because we are evaluating a top level variable)
+     * @param property Property name to be accessed
+     */
+    public Class getType(ELContext context, Object base, Object property) {
+
+        if ((base == null) || (property == null)) {
+            return null;
+        }
+
+        context.setPropertyResolved(true);
+        FacesContext fcontext = (FacesContext) context.getContext(FacesContext.class);
+        ELContext elContext = fcontext.getELContext();
+        PropertyResolver pr = fcontext.getApplication().getPropertyResolver();
+
+        if ((base instanceof List) || base.getClass().isArray()) {
+            Integer index = (Integer) fcontext.getApplication().getExpressionFactory().
+                    coerceToType(property, Integer.class);
+            try {
+                return pr.getType(base, index.intValue());
+            } catch (EvaluationException e) {
+                context.setPropertyResolved(false);
+                throw new ELException(e);
+            }
+        } else {
+            try {
+                return pr.getType(base, property);
+            } catch (EvaluationException e) {
+                context.setPropertyResolved(false);
+                throw new ELException(e);
+            }
+        }
+
+    }
+
+
+    /**
+     * <p>Evaluate with the legacy property resolver chain and return
+     * the value.</p>
+     *
+     * @param context <code>ELContext</code> for evaluating this value
+     * @param base Base object against which this evaluation occurs
+     *  (must be null because we are evaluating a top level variable)
+     * @param property Property name to be accessed
+     */
+    public Object getValue(ELContext context, Object base, Object property) {
+
+        if ((base == null) || (property == null)) {
+            return null;
+        }
+
+        context.setPropertyResolved(true);
+        FacesContext fcontext = (FacesContext) context.getContext(FacesContext.class);
+        ELContext elContext = fcontext.getELContext();
+        PropertyResolver pr = fcontext.getApplication().getPropertyResolver();
+
+        if ((base instanceof List) || base.getClass().isArray()) {
+            Integer index = (Integer) fcontext.getApplication().getExpressionFactory().
+                    coerceToType(property, Integer.class);
+            try {
+                return pr.getValue(base, index.intValue());
+            } catch (EvaluationException e) {
+                context.setPropertyResolved(false);
+                throw new ELException(e);
+            }
+        } else {
+            try {
+                return pr.getValue(base, property);
+            } catch (EvaluationException e) {
+                context.setPropertyResolved(false);
+                throw new ELException(e);
+            }
+        }
+
+    }
+
+
+    /**
+     * <p>Return <code>true</code> if the specified property is read only.</p>
+     *
+     * @param context <code>ELContext</code> for evaluating this value
+     * @param base Base object against which this evaluation occurs
+     *  (must be null because we are evaluating a top level variable)
+     * @param property Property name to be accessed
+     */
+    public boolean isReadOnly(ELContext context, Object base, Object property) {
+
+        if ((base == null) || (property == null)) {
+            return false;
+        }
+
+        context.setPropertyResolved(true);
+        FacesContext fcontext = (FacesContext) context.getContext(FacesContext.class);
+        ELContext elContext = fcontext.getELContext();
+        PropertyResolver pr = fcontext.getApplication().getPropertyResolver();
+
+        if ((base instanceof List) || base.getClass().isArray()) {
+            Integer index = (Integer) fcontext.getApplication().getExpressionFactory().
+                    coerceToType(property, Integer.class);
+            try {
+                return pr.isReadOnly(base, index.intValue());
+            } catch (EvaluationException e) {
+                context.setPropertyResolved(false);
+                throw new ELException(e);
+            }
+        } else {
+            try {
+                return pr.isReadOnly(base, property);
+            } catch (EvaluationException e) {
+                context.setPropertyResolved(false);
+                throw new ELException(e);
+            }
+        }
+
+    }
+
+
+
+    /**
+     * <p>Set the value of a property for the specified name.</p>
+     *
+     * @param context <code>ELContext</code> for evaluating this value
+     * @param base Base object against which this evaluation occurs
+     *  (must be null because we are evaluating a top level variable)
+     * @param property Property name to be accessed
+     * @param value New value to be set
+     */
+    public void setValue(ELContext context, Object base, Object property, Object value) {
+
+        if ((base == null) || (property == null)) {
+            return;
+        }
+
+        context.setPropertyResolved(true);
+        FacesContext fcontext = (FacesContext) context.getContext(FacesContext.class);
+        ELContext elContext = fcontext.getELContext();
+        PropertyResolver pr = fcontext.getApplication().getPropertyResolver();
+
+        if ((base instanceof List) || base.getClass().isArray()) {
+            Integer index = (Integer) fcontext.getApplication().getExpressionFactory().
+                    coerceToType(property, Integer.class);
+            try {
+                pr.setValue(base, index.intValue(), value);
+            } catch (EvaluationException e) {
+                context.setPropertyResolved(false);
+                throw new ELException(e);
+            }
+        } else {
+            try {
+                pr.setValue(base, property, value);
+            } catch (EvaluationException e) {
+                context.setPropertyResolved(false);
+                throw new ELException(e);
+            }
+        }
+
+    }
+
+
+}

Added: shale/framework/trunk/shale-test/src/main/java/org/apache/shale/test/el/FacesResourceBundleELResolver.java
URL: http://svn.apache.org/viewvc/shale/framework/trunk/shale-test/src/main/java/org/apache/shale/test/el/FacesResourceBundleELResolver.java?view=auto&rev=454044
==============================================================================
--- shale/framework/trunk/shale-test/src/main/java/org/apache/shale/test/el/FacesResourceBundleELResolver.java (added)
+++ shale/framework/trunk/shale-test/src/main/java/org/apache/shale/test/el/FacesResourceBundleELResolver.java Sat Oct  7 16:34:51 2006
@@ -0,0 +1,214 @@
+/*
+ * Copyright 2006 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.shale.test.el;
+
+import java.beans.FeatureDescriptor;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.ResourceBundle;
+import java.util.Set;
+import javax.el.ELContext;
+import javax.el.ELResolver;
+import javax.el.PropertyNotFoundException;
+import javax.el.PropertyNotWritableException;
+import javax.faces.application.Application;
+import javax.faces.context.FacesContext;
+import org.apache.shale.test.mock.MockApplication12;
+
+/**
+ * <p><code>ELResolver</code> implementation that accesses resource bundles
+ * in the current application.  See the JSF 1.2 Specification, section
+ * 5.6.1.3, for requirements implemented by this class.</p>
+ *
+ * @since 1.0.4
+ */
+public class FacesResourceBundleELResolver extends AbstractELResolver {
+    
+
+    /**
+     * <p>Return the most general type this resolver accepts for the
+     * <code>property</code> argument.</p>
+     */
+    public Class getCommonPropertyType(ELContext context, Object base) {
+
+        if (base != null) {
+            return null;
+        } else {
+            return String.class;
+        }
+
+    }
+
+
+    /**
+     * <p>Return an <code>Iterator</code> over the attributes that this
+     * resolver knows how to deal with.</p>
+     *
+     * @param context <code>ELContext</code> for evaluating this value
+     * @param base Base object against which this evaluation occurs
+     */
+    public Iterator getFeatureDescriptors(ELContext context, Object base) {
+
+        if (base != null) {
+            return null;
+        }
+
+        // Create the variables we will need
+        List descriptors = new ArrayList();
+        FacesContext fcontext = (FacesContext) context.getContext(FacesContext.class);
+        MockApplication12 application =
+                (MockApplication12) fcontext.getApplication();
+        String key = null;
+        Object value = null;
+
+        // Create a feature descriptor for each configured resource bundle
+        Iterator entries = application.getResourceBundles().entrySet().iterator();
+        while (entries.hasNext()) {
+            Entry entry = (Entry) entries.next();
+            key = (String) entry.getKey();
+            value = entry.getValue();
+            descriptors.add(descriptor(key, key, "Resource Bundle " + key,
+                                       false, false, true,
+                                       ResourceBundle.class, true));
+        }
+
+        // Return the accumulated descriptors
+        return descriptors.iterator();
+
+    }
+
+
+    /**
+     * <p>Return the Java type of the specified property.</p>
+     *
+     * @param context <code>ELContext</code> for evaluating this value
+     * @param base Base object against which this evaluation occurs
+     *  (must be null because we are evaluating a top level variable)
+     * @param property Property name to be accessed
+     */
+    public Class getType(ELContext context, Object base, Object property) {
+
+        if (base != null) {
+            return null;
+        }
+        if (property == null) {
+            throw new PropertyNotFoundException("No property specified");
+        }
+        FacesContext fcontext = (FacesContext) context.getContext(FacesContext.class);
+        ResourceBundle bundle =
+          fcontext.getApplication().getResourceBundle(fcontext, property.toString());
+        if (bundle != null) {
+            context.setPropertyResolved(true);
+            return ResourceBundle.class;
+        }
+        return null;
+
+    }
+
+
+    /**
+     * <p>Return a resource bundle for the specified name (if any);
+     * otherwise, return <code>null</code>.</p>
+     *
+     * @param context <code>ELContext</code> for evaluating this value
+     * @param base Base object against which this evaluation occurs
+     *  (must be null because we are evaluating a top level variable)
+     * @param property Property name to be accessed
+     */
+    public Object getValue(ELContext context, Object base, Object property) {
+
+        if (base != null) {
+            return null;
+        }
+        if (property == null) {
+            throw new PropertyNotFoundException("No property specified");
+        }
+
+        FacesContext fcontext = (FacesContext) context.getContext(FacesContext.class);
+        ResourceBundle bundle =
+          fcontext.getApplication().getResourceBundle(fcontext, property.toString());
+        if (bundle != null) {
+            context.setPropertyResolved(true);
+            return bundle;
+        }
+        return null;
+
+    }
+
+
+    /**
+     * <p>Return <code>true</code> if the specified property is read only.</p>
+     *
+     * @param context <code>ELContext</code> for evaluating this value
+     * @param base Base object against which this evaluation occurs
+     *  (must be null because we are evaluating a top level variable)
+     * @param property Property name to be accessed
+     */
+    public boolean isReadOnly(ELContext context, Object base, Object property) {
+
+        if (base != null) {
+            return false;
+        }
+        if (property == null) {
+            throw new PropertyNotFoundException("No property specified");
+        }
+        FacesContext fcontext = (FacesContext) context.getContext(FacesContext.class);
+        ResourceBundle bundle =
+          fcontext.getApplication().getResourceBundle(fcontext, property.toString());
+        if (bundle != null) {
+            context.setPropertyResolved(true);
+            return true;
+        }
+        return false;
+
+    }
+
+
+
+    /**
+     * <p>Set the value of a scoped object for the specified name.</p>
+     *
+     * @param context <code>ELContext</code> for evaluating this value
+     * @param base Base object against which this evaluation occurs
+     *  (must be null because we are evaluating a top level variable)
+     * @param property Property name to be accessed
+     * @param value New value to be set
+     */
+    public void setValue(ELContext context, Object base, Object property, Object value) {
+
+        if (base != null) {
+            return;
+        }
+        if (property == null) {
+            throw new PropertyNotFoundException("No property specified");
+        }
+
+        FacesContext fcontext = (FacesContext) context.getContext(FacesContext.class);
+        ResourceBundle bundle =
+          fcontext.getApplication().getResourceBundle(fcontext, property.toString());
+        if (bundle != null) {
+            context.setPropertyResolved(true);
+            throw new PropertyNotWritableException(property.toString());
+        }
+
+    }
+
+
+}

Added: shale/framework/trunk/shale-test/src/main/java/org/apache/shale/test/el/FacesScopedAttributeELResolver.java
URL: http://svn.apache.org/viewvc/shale/framework/trunk/shale-test/src/main/java/org/apache/shale/test/el/FacesScopedAttributeELResolver.java?view=auto&rev=454044
==============================================================================
--- shale/framework/trunk/shale-test/src/main/java/org/apache/shale/test/el/FacesScopedAttributeELResolver.java (added)
+++ shale/framework/trunk/shale-test/src/main/java/org/apache/shale/test/el/FacesScopedAttributeELResolver.java Sat Oct  7 16:34:51 2006
@@ -0,0 +1,241 @@
+/*
+ * Copyright 2006 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.shale.test.el;
+
+import java.beans.FeatureDescriptor;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Set;
+import javax.el.ELContext;
+import javax.el.ELResolver;
+import javax.el.PropertyNotFoundException;
+import javax.faces.context.ExternalContext;
+import javax.faces.context.FacesContext;
+
+/**
+ * <p><code>ELResolver</code> implementation that accesses scoped variables
+ * in the current request context.  See the JSF 1.2 Specification, section
+ * 5.6.2.7, for requirements implemented by this class.</p>
+ *
+ * @since 1.0.4
+ */
+public class FacesScopedAttributeELResolver extends AbstractELResolver {
+    
+
+    /**
+     * <p>Return the most general type this resolver accepts for the
+     * <code>property</code> argument.</p>
+     */
+    public Class getCommonPropertyType(ELContext context, Object base) {
+
+        if (base != null) {
+            return null;
+        } else {
+            return String.class;
+        }
+
+    }
+
+
+    /**
+     * <p>Return an <code>Iterator</code> over the attributes that this
+     * resolver knows how to deal with.</p>
+     *
+     * @param context <code>ELContext</code> for evaluating this value
+     * @param base Base object against which this evaluation occurs
+     */
+    public Iterator getFeatureDescriptors(ELContext context, Object base) {
+
+        if (base != null) {
+            return null;
+        }
+
+        // Create the variables we will need
+        FacesContext fcontext = (FacesContext) context.getContext(FacesContext.class);
+        ExternalContext econtext = fcontext.getExternalContext();
+        List descriptors = new ArrayList();
+        Map map = null;
+        Set set = null;
+        Iterator items = null;
+        String key = null;
+        Object value = null;
+
+        // Add feature descriptors for request scoped attributes
+        set = econtext.getRequestMap().entrySet();
+        items = set.iterator();
+        while (items.hasNext()) {
+            Entry item = (Entry) items.next();
+            key = (String) item.getKey();
+            value = item.getValue();
+            descriptors.add(descriptor(key, key, "Request Scope Attribute " + key,
+                                       false, false, true, value.getClass(), true));
+        }
+
+        // Add feature descriptors for session scoped attributes
+        set = econtext.getSessionMap().entrySet();
+        items = set.iterator();
+        while (items.hasNext()) {
+            Entry item = (Entry) items.next();
+            key = (String) item.getKey();
+            value = item.getValue();
+            descriptors.add(descriptor(key, key, "Session Scope Attribute " + key,
+                                       false, false, true, value.getClass(), true));
+        }
+
+        // Add feature descriptors for application scoped attributes
+        set = econtext.getApplicationMap().entrySet();
+        items = set.iterator();
+        while (items.hasNext()) {
+            Entry item = (Entry) items.next();
+            key = (String) item.getKey();
+            value = item.getValue();
+            descriptors.add(descriptor(key, key, "Application Scope Attribute " + key,
+                                       false, false, true, value.getClass(), true));
+        }
+
+        // Return the accumulated descriptors
+        return descriptors.iterator();
+
+    }
+
+
+
+    /**
+     * <p>Return the Java type of the specified property.</p>
+     *
+     * @param context <code>ELContext</code> for evaluating this value
+     * @param base Base object against which this evaluation occurs
+     *  (must be null because we are evaluating a top level variable)
+     * @param property Property name to be accessed
+     */
+    public Class getType(ELContext context, Object base, Object property) {
+
+        if (base != null) {
+            return null;
+        }
+        if (property == null) {
+            throw new PropertyNotFoundException("No property specified");
+        }
+        context.setPropertyResolved(true);
+        return Object.class;
+
+    }
+
+
+    /**
+     * <p>Return an existing scoped object for the specified name (if any);
+     * otherwise, return <code>null</code>.</p>
+     *
+     * @param context <code>ELContext</code> for evaluating this value
+     * @param base Base object against which this evaluation occurs
+     *  (must be null because we are evaluating a top level variable)
+     * @param property Property name to be accessed
+     */
+    public Object getValue(ELContext context, Object base, Object property) {
+
+        if (base != null) {
+            return null;
+        }
+        if (property == null) {
+            throw new PropertyNotFoundException("No property specified");
+        }
+
+        FacesContext fcontext = (FacesContext) context.getContext(FacesContext.class);
+        ExternalContext econtext = fcontext.getExternalContext();
+        Object value = null;
+        value = econtext.getRequestMap().get(property);
+        if (value != null) {
+            context.setPropertyResolved(true);
+            return value;
+        }
+        value = econtext.getSessionMap().get(property);
+        if (value != null) {
+            context.setPropertyResolved(true);
+            return value;
+        }
+        value = econtext.getApplicationMap().get(property);
+        if (value != null) {
+            context.setPropertyResolved(true);
+            return value;
+        }
+
+        return null;
+
+    }
+
+
+    /**
+     * <p>Return <code>true</code> if the specified property is read only.</p>
+     *
+     * @param context <code>ELContext</code> for evaluating this value
+     * @param base Base object against which this evaluation occurs
+     *  (must be null because we are evaluating a top level variable)
+     * @param property Property name to be accessed
+     */
+    public boolean isReadOnly(ELContext context, Object base, Object property) {
+
+        if (base == null) {
+            context.setPropertyResolved(true);
+            return false;
+        }
+        return false;
+
+    }
+
+
+
+    /**
+     * <p>Set the value of a scoped object for the specified name.</p>
+     *
+     * @param context <code>ELContext</code> for evaluating this value
+     * @param base Base object against which this evaluation occurs
+     *  (must be null because we are evaluating a top level variable)
+     * @param property Property name to be accessed
+     * @param value New value to be set
+     */
+    public void setValue(ELContext context, Object base, Object property, Object value) {
+
+        if (base != null) {
+            return;
+        }
+        if (property == null) {
+            throw new PropertyNotFoundException("No property specified");
+        }
+
+        context.setPropertyResolved(true);
+        String key = property.toString();
+        Object result = null;
+        FacesContext fcontext = (FacesContext) context.getContext(FacesContext.class);
+        ExternalContext econtext = fcontext.getExternalContext();
+
+        if (econtext.getRequestMap().containsKey(property)) {
+            econtext.getRequestMap().put(key, value);
+        } else if (econtext.getSessionMap().containsKey(property)) {
+            econtext.getSessionMap().put(key, value);
+        } else if (econtext.getApplicationMap().containsKey(property)) {
+            econtext.getApplicationMap().put(key, value);
+        } else {
+            econtext.getRequestMap().put(key, value);
+        }
+
+    }
+
+
+}

Added: shale/framework/trunk/shale-test/src/main/java/org/apache/shale/test/el/FacesVariableResolverChainWrapper.java
URL: http://svn.apache.org/viewvc/shale/framework/trunk/shale-test/src/main/java/org/apache/shale/test/el/FacesVariableResolverChainWrapper.java?view=auto&rev=454044
==============================================================================
--- shale/framework/trunk/shale-test/src/main/java/org/apache/shale/test/el/FacesVariableResolverChainWrapper.java (added)
+++ shale/framework/trunk/shale-test/src/main/java/org/apache/shale/test/el/FacesVariableResolverChainWrapper.java Sat Oct  7 16:34:51 2006
@@ -0,0 +1,166 @@
+/*
+ * Copyright 2006 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.shale.test.el;
+
+import java.beans.FeatureDescriptor;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Set;
+import javax.el.ELContext;
+import javax.el.ELException;
+import javax.el.ELResolver;
+import javax.el.PropertyNotFoundException;
+import javax.el.PropertyNotWritableException;
+import javax.faces.component.UIViewRoot;
+import javax.faces.context.ExternalContext;
+import javax.faces.context.FacesContext;
+import javax.faces.el.VariableResolver;
+
+/**
+ * <p><code>ELResolver</code> implementation that wraps the legacy (JSF 1.1)
+ * <code>VariableResolver</code> chain.  See the JSF 1.2 Specification, section
+ * 5.6.1.5, for requirements implemented by this class.</p>
+ *
+ * @since 1.0.4
+ */
+public class FacesVariableResolverChainWrapper extends AbstractELResolver {
+    
+
+    /**
+     * <p>Return the most general type this resolver accepts for the
+     * <code>property</code> argument.</p>
+     */
+    public Class getCommonPropertyType(ELContext context, Object base) {
+
+        if (base != null) {
+            return null;
+        } else {
+            return String.class;
+        }
+
+    }
+
+
+    /**
+     * <p>Return an <code>Iterator</code> over the attributes that this
+     * resolver knows how to deal with.</p>
+     *
+     * @param context <code>ELContext</code> for evaluating this value
+     * @param base Base object against which this evaluation occurs
+     */
+    public Iterator getFeatureDescriptors(ELContext context, Object base) {
+
+        return null;
+
+    }
+
+
+
+    /**
+     * <p>Return the Java type of the specified property.</p>
+     *
+     * @param context <code>ELContext</code> for evaluating this value
+     * @param base Base object against which this evaluation occurs
+     *  (must be null because we are evaluating a top level variable)
+     * @param property Property name to be accessed
+     */
+    public Class getType(ELContext context, Object base, Object property) {
+
+        if ((base == null) && (property == null)) {
+            throw new PropertyNotFoundException("No property specified");
+        }
+        return null;
+
+    }
+
+
+    /**
+     * <p>Evaluate with the legacy variable resolver chain and return
+     * the value.</p>
+     *
+     * @param context <code>ELContext</code> for evaluating this value
+     * @param base Base object against which this evaluation occurs
+     *  (must be null because we are evaluating a top level variable)
+     * @param property Property name to be accessed
+     */
+    public Object getValue(ELContext context, Object base, Object property) {
+
+        if (base != null) {
+            return null;
+        }
+        if (property == null) {
+            throw new PropertyNotFoundException("No property specified");
+        }
+
+        FacesContext fcontext = (FacesContext) context.getContext(FacesContext.class);
+        ExternalContext econtext = fcontext.getExternalContext();
+        String name = property.toString();
+
+        context.setPropertyResolved(true);
+        ELContext elContext = fcontext.getELContext();
+        VariableResolver vr = fcontext.getApplication().getVariableResolver();
+        try {
+            return vr.resolveVariable(fcontext, name);
+        } catch (Exception e) {
+            context.setPropertyResolved(false);
+            throw new ELException(e);
+        }
+
+    }
+
+
+    /**
+     * <p>Return <code>true</code> if the specified property is read only.</p>
+     *
+     * @param context <code>ELContext</code> for evaluating this value
+     * @param base Base object against which this evaluation occurs
+     *  (must be null because we are evaluating a top level variable)
+     * @param property Property name to be accessed
+     */
+    public boolean isReadOnly(ELContext context, Object base, Object property) {
+
+        if ((base == null) && (property == null)) {
+            throw new PropertyNotFoundException("No property specified");
+        }
+        return false;
+
+    }
+
+
+
+    /**
+     * <p>Set the value of a scoped object for the specified name.</p>
+     *
+     * @param context <code>ELContext</code> for evaluating this value
+     * @param base Base object against which this evaluation occurs
+     *  (must be null because we are evaluating a top level variable)
+     * @param property Property name to be accessed
+     * @param value New value to be set
+     */
+    public void setValue(ELContext context, Object base, Object property, Object value) {
+
+        if ((base == null) && (property == null)) {
+            throw new PropertyNotFoundException("No property specified");
+        }
+
+    }
+
+
+}

Modified: shale/framework/trunk/shale-test/src/main/java/org/apache/shale/test/mock/MockApplication12.java
URL: http://svn.apache.org/viewvc/shale/framework/trunk/shale-test/src/main/java/org/apache/shale/test/mock/MockApplication12.java?view=diff&rev=454044&r1=454043&r2=454044
==============================================================================
--- shale/framework/trunk/shale-test/src/main/java/org/apache/shale/test/mock/MockApplication12.java (original)
+++ shale/framework/trunk/shale-test/src/main/java/org/apache/shale/test/mock/MockApplication12.java Sat Oct  7 16:34:51 2006
@@ -17,19 +17,31 @@
 package org.apache.shale.test.mock;
 
 import java.util.ArrayList;
+import java.util.HashMap;
 import java.util.Iterator;
 import java.util.List;
 import java.util.Locale;
+import java.util.Map;
 import java.util.ResourceBundle;
+import javax.el.ArrayELResolver;
+import javax.el.BeanELResolver;
 import javax.el.CompositeELResolver;
 import javax.el.ELContextListener;
 import javax.el.ELException;
 import javax.el.ELResolver;
 import javax.el.ExpressionFactory;
+import javax.el.ListELResolver;
+import javax.el.MapELResolver;
+import javax.el.ResourceBundleELResolver;
 import javax.el.ValueExpression;
 import javax.faces.component.UIComponent;
 import javax.faces.component.UIViewRoot;
 import javax.faces.context.FacesContext;
+import org.apache.shale.test.el.FacesImplicitObjectELResolver;
+import org.apache.shale.test.el.FacesPropertyResolverChainWrapper;
+import org.apache.shale.test.el.FacesResourceBundleELResolver;
+import org.apache.shale.test.el.FacesScopedAttributeELResolver;
+import org.apache.shale.test.el.FacesVariableResolverChainWrapper;
 
 /**
  * <p>Mock implementation of <code>ExternalContext</code> that includes the semantics
@@ -54,7 +66,6 @@
 
         // Configure our expression factory and EL resolvers
         expressionFactory = new MockExpressionFactory();
-        // FIXME - configure elResolvers list with standard resolvers
 
     }
 
@@ -63,6 +74,12 @@
 
 
     /**
+     * <p>A list of resource bundles configured for this application.</p>
+     */
+    private Map bundles = new HashMap();
+
+
+    /**
      * <p>The set of configured ELContextListener instances.</p>
      */
     private List elContextListeners = new ArrayList();
@@ -90,6 +107,27 @@
     // ----------------------------------------------------- Mock Object Methods
 
 
+    /**
+     * <p>Add the specified resource bundle to those associated with
+     * this application.</p>
+     *
+     * @param name Name under which to add this resource bundle
+     * @param bundle ResourceBundle to add
+     */
+    public void addResourceBundle(String name, ResourceBundle bundle) {
+        bundles.put(name, bundle);
+    }
+
+
+    /**
+     * <p>Return a <code>Map</code> of the resource bundles configured
+     * for this application, keyed by name.</p>
+     */
+    public Map getResourceBundles() {
+        return bundles;
+    }
+
+
     // ----------------------------------------------------- Application Methods
 
 
@@ -150,12 +188,34 @@
     public ELResolver getELResolver() {
 
         if (resolver == null) {
+
+            // Configure a default ELResolver per Section 5.6.2 of JSF 1.2
             CompositeELResolver composite = new CompositeELResolver();
+
+            composite.add(new FacesImplicitObjectELResolver());
+
+            CompositeELResolver nested = new CompositeELResolver();
+            // FIXME - nested.add() "ELResolvers from application configuration resources"
+            nested.add(new FacesVariableResolverChainWrapper());
+            nested.add(new FacesPropertyResolverChainWrapper());
             Iterator items = resolvers.iterator();
             while (items.hasNext()) {
-                composite.add((ELResolver) items.next());
+                nested.add((ELResolver) items.next());
             }
+            composite.add(nested);
+
+            // composite.add(new faces.ManagedBeanELResolver()); // FIXME
+            composite.add(new ResourceBundleELResolver());
+            composite.add(new FacesResourceBundleELResolver());
+            composite.add(new MapELResolver());
+            composite.add(new ListELResolver());
+            composite.add(new ArrayELResolver());
+            composite.add(new BeanELResolver());
+            composite.add(new FacesScopedAttributeELResolver());
+
+            // Make the resolver we have configured the application wide one
             resolver = composite;
+
         }
         return resolver;