[seam-commits] Seam SVN: r9684 - in trunk/src: main/org/jboss/seam/init and 3 other directories.

seam-commits at lists.jboss.org seam-commits at lists.jboss.org
Mon Dec 1 16:41:20 EST 2008


Author: dan.j.allen
Date: 2008-12-01 16:41:20 -0500 (Mon, 01 Dec 2008)
New Revision: 9684

Added:
   trunk/src/test/unit/org/jboss/seam/test/unit/ExpressionsTest.java
Modified:
   trunk/src/main/org/jboss/seam/faces/FacesExpressions.java
   trunk/src/main/org/jboss/seam/init/Initialization.java
   trunk/src/main/org/jboss/seam/mock/MockExternalContext.java
   trunk/src/main/org/jboss/seam/navigation/Param.java
   trunk/src/test/unit/org/jboss/seam/test/unit/PageParamTest.java
Log:
JBSEAM-3674

Modified: trunk/src/main/org/jboss/seam/faces/FacesExpressions.java
===================================================================
--- trunk/src/main/org/jboss/seam/faces/FacesExpressions.java	2008-12-01 21:40:20 UTC (rev 9683)
+++ trunk/src/main/org/jboss/seam/faces/FacesExpressions.java	2008-12-01 21:41:20 UTC (rev 9684)
@@ -33,15 +33,13 @@
    @Override
    public ELContext getELContext()
    {
-      FacesContext facesContext = FacesContext.getCurrentInstance();
-      return facesContext == null || FacesLifecycle.getPhaseId() == null
-         ? super.getELContext() : facesContext.getELContext();
+      return isFacesContextActive() ? FacesContext.getCurrentInstance().getELContext() : super.getELContext();
    }
    
    @Override
    protected boolean isFacesContextActive()
    { 
-      return FacesContext.getCurrentInstance()==null; 
+      return FacesContext.getCurrentInstance() != null && FacesLifecycle.getPhaseId() != null;
    }
    
 }

Modified: trunk/src/main/org/jboss/seam/init/Initialization.java
===================================================================
--- trunk/src/main/org/jboss/seam/init/Initialization.java	2008-12-01 21:40:20 UTC (rev 9683)
+++ trunk/src/main/org/jboss/seam/init/Initialization.java	2008-12-01 21:41:20 UTC (rev 9684)
@@ -45,6 +45,7 @@
 import org.jboss.seam.bpm.Jbpm;
 import org.jboss.seam.contexts.Context;
 import org.jboss.seam.contexts.Contexts;
+import org.jboss.seam.contexts.Lifecycle;
 import org.jboss.seam.contexts.ServletLifecycle;
 import org.jboss.seam.core.Expressions;
 import org.jboss.seam.core.Init;
@@ -758,7 +759,6 @@
             
             boolean changed = new TimestampCheckForwardingDeploymentStrategy()
             {
-               
                @Override
                protected DeploymentStrategy delegate()
                {
@@ -806,7 +806,6 @@
             final WarRootDeploymentStrategy warRootDeploymentStrategy = new WarRootDeploymentStrategy(Thread.currentThread().getContextClassLoader(), warRoot, new File[] { warClassesDirectory, warLibDirectory, hotDeployDirectory });
             changed = new TimestampCheckForwardingDeploymentStrategy()
             {
-               
                @Override
                protected DeploymentStrategy delegate()
                {
@@ -822,7 +821,10 @@
                   log.info("redeploying page descriptors...");
                   Pages pages = (Pages) ServletLifecycle.getServletContext().getAttribute(Seam.getComponentName(Pages.class));
                   if (pages != null) {
-                      pages.initialize(warRootDeploymentStrategy.getDotPageDotXmlFileNames());
+                     // application context is needed for creating expressions
+                     Lifecycle.mockApplication();
+                     pages.initialize(warRootDeploymentStrategy.getDotPageDotXmlFileNames());
+                     Lifecycle.unmockApplication();
                   }
                   ServletLifecycle.getServletContext().removeAttribute(Seam.getComponentName(Exceptions.class));
                   init.setWarTimestamp(warRootDeploymentStrategy.getTimestamp());

Modified: trunk/src/main/org/jboss/seam/mock/MockExternalContext.java
===================================================================
--- trunk/src/main/org/jboss/seam/mock/MockExternalContext.java	2008-12-01 21:40:20 UTC (rev 9683)
+++ trunk/src/main/org/jboss/seam/mock/MockExternalContext.java	2008-12-01 21:41:20 UTC (rev 9684)
@@ -80,6 +80,11 @@
       this.request = request;
       this.response = response;
    }
+   
+   public MockExternalContext(HttpServletRequest request)
+   {
+      this.request = request;
+   }
 
    @Override
    public void dispatch(String url) throws IOException

Modified: trunk/src/main/org/jboss/seam/navigation/Param.java
===================================================================
--- trunk/src/main/org/jboss/seam/navigation/Param.java	2008-12-01 21:40:20 UTC (rev 9683)
+++ trunk/src/main/org/jboss/seam/navigation/Param.java	2008-12-01 21:41:20 UTC (rev 9684)
@@ -63,6 +63,10 @@
       else
       {
          Class<?> type = valueExpression.getType();
+         if (type==null)
+         {
+            return null;
+         }
          return FacesContext.getCurrentInstance().getApplication().createConverter(type);           
       }
    }

Added: trunk/src/test/unit/org/jboss/seam/test/unit/ExpressionsTest.java
===================================================================
--- trunk/src/test/unit/org/jboss/seam/test/unit/ExpressionsTest.java	                        (rev 0)
+++ trunk/src/test/unit/org/jboss/seam/test/unit/ExpressionsTest.java	2008-12-01 21:41:20 UTC (rev 9684)
@@ -0,0 +1,132 @@
+package org.jboss.seam.test.unit;
+
+import static org.testng.Assert.assertEquals;
+
+import java.beans.FeatureDescriptor;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+
+import javax.el.ELContext;
+import javax.el.ELResolver;
+import javax.el.PropertyNotFoundException;
+import javax.faces.application.Application;
+import javax.faces.context.ExternalContext;
+import javax.faces.context.FacesContext;
+import javax.faces.event.PhaseId;
+
+import org.jboss.seam.contexts.FacesLifecycle;
+import org.jboss.seam.core.Expressions;
+import org.jboss.seam.faces.FacesExpressions;
+import org.jboss.seam.mock.MockApplication;
+import org.jboss.seam.mock.MockExternalContext;
+import org.jboss.seam.mock.MockFacesContext;
+import org.jboss.seam.mock.MockHttpServletRequest;
+import org.jboss.seam.mock.MockHttpSession;
+import org.testng.annotations.Test;
+
+public class ExpressionsTest
+{
+   /**
+    * Validate that FacesExpressions reports that the FacesContext is activate and
+    * returns the Faces-aware EL context so that a Faces-specific expression can
+    * be resolved through Seam's built-in expression resolver.
+    * @jira JBSEAM-3674
+    */
+   @Test
+   public void testExpressionResolvedInFacesELContext()
+   {
+      Map<String, String> params = new HashMap<String, String>();
+      params.put("foo", "bar");
+      FacesContext facesContext = setupFacesContextToAccessRequestParams(params);
+      String expr = "#{param.foo}";
+      
+      // the control
+      assertEquals(facesContext.getApplication().evaluateExpressionGet(facesContext, expr, Object.class), "bar");
+      
+      // the test
+      FacesLifecycle.setPhaseId(PhaseId.INVOKE_APPLICATION);
+      Expressions expressions = new FacesExpressions();
+      assert expressions.getELContext().getContext(FacesContext.class) != null;
+      assertEquals(expressions.createValueExpression(expr).getValue(), "bar");
+   }
+   
+   protected FacesContext setupFacesContextToAccessRequestParams(Map<String, String> params)
+   {
+      MockHttpServletRequest request = new MockHttpServletRequest(new MockHttpSession());
+      if (params != null)
+      {
+         for (Map.Entry<String, String> param : params.entrySet())
+         {
+            request.getParameterMap().put(param.getKey(), new String[] { param.getValue() });
+         }
+      }
+      ExternalContext extContext = new MockExternalContext(request);
+      Application application = new MockApplication();
+      application.addELResolver(new ImplicitObjectELResolver());
+      FacesContext facesCtx = new MockFacesContext(extContext, application).setCurrent();
+      assert FacesContext.getCurrentInstance() != null;
+      return facesCtx;
+   }
+   
+   /**
+    * This resolver resolves select implicit objects that are available to the EL during a Faces request.
+    * It must be implemented here since it is part of the JSF RI, not the API.
+    */
+   class ImplicitObjectELResolver extends ELResolver
+   {
+      private final String PARAM = "param";
+      
+      private final String[] IMPLICIT_OBJECT_NAMES = new String[] { PARAM };
+      
+      @Override
+      public Class<?> getCommonPropertyType(ELContext ctx, Object base)
+      {
+         return null;
+      }
+
+      @Override
+      public Iterator<FeatureDescriptor> getFeatureDescriptors(ELContext ctx, Object base)
+      {
+         return null;
+      }
+
+      @Override
+      public Class<?> getType(ELContext ctx, Object base, Object prop)
+      {
+         return null;
+      }
+
+      @Override
+      public Object getValue(ELContext elCtx, Object base, Object prop)
+      {
+         if (base != null) return null;
+         
+         if (prop == null) throw new PropertyNotFoundException("No such property " + prop);
+
+         int idx = Arrays.binarySearch(IMPLICIT_OBJECT_NAMES, prop);
+         if (idx < 0) return null;
+         
+         FacesContext facesCtx = (FacesContext) elCtx.getContext(FacesContext.class);
+         ExternalContext extCtx = facesCtx.getExternalContext();
+         
+         if (prop.equals(PARAM))
+         {
+            elCtx.setPropertyResolved(true);
+            return extCtx.getRequestParameterMap();
+         }
+
+         throw new IllegalStateException("Programming error: list of possible conditions is incomplete");
+      }
+
+      @Override
+      public boolean isReadOnly(ELContext ctx, Object base, Object prop)
+      {
+         return true;
+      }
+
+      @Override
+      public void setValue(ELContext ctx, Object base, Object prop, Object value) {}
+   }
+}

Modified: trunk/src/test/unit/org/jboss/seam/test/unit/PageParamTest.java
===================================================================
--- trunk/src/test/unit/org/jboss/seam/test/unit/PageParamTest.java	2008-12-01 21:40:20 UTC (rev 9683)
+++ trunk/src/test/unit/org/jboss/seam/test/unit/PageParamTest.java	2008-12-01 21:41:20 UTC (rev 9684)
@@ -1,17 +1,28 @@
 package org.jboss.seam.test.unit;
 
+import java.util.HashMap;
+
 import javax.faces.component.UIComponent;
 import javax.faces.context.FacesContext;
 import javax.faces.convert.IntegerConverter;
 import javax.faces.validator.Validator;
 import javax.faces.validator.ValidatorException;
 
+import org.jboss.seam.contexts.Lifecycle;
+import org.jboss.seam.core.Expressions;
+import org.jboss.seam.jsf.SeamApplication;
 import org.jboss.seam.mock.MockApplication;
 import org.jboss.seam.mock.MockExternalContext;
 import org.jboss.seam.mock.MockFacesContext;
 import org.jboss.seam.navigation.Param;
 import org.testng.annotations.Test;
 
+/**
+ * Verifies that page parameters are setup properly and report the correct information
+ * about validators and converters.
+ * 
+ * @author Dan Allen
+ */
 public class PageParamTest
 {
    @Test
@@ -19,31 +30,51 @@
    {
       String converterId = "javax.faces.Integer";
       String converterClass = "javax.faces.convert.IntegerConverter";
-      MockFacesContext facesContext = new MockFacesContext(new MockExternalContext(), new MockApplication());
-      facesContext.setCurrent();
+      setupMockFacesContextWithSeamApplication();
       Param param = new Param("param");
       param.setConverterId(converterId);
       assert param.getConverter() instanceof IntegerConverter : "expecting: " + converterClass + "; got: " + param.getConverter();
    }
    
+   /**
+    * Verify that converter is null when the parameter value is a value expression and
+    * we are operating outside of a FacesContext.
+    * @jira JBSEAM-3674
+    */
    @Test
+   public void testConverterIsNullForNonFacesValueExpression()
+   {
+      setupMockFacesContextWithSeamApplication();
+      Param param = new Param("param");
+      param.setValueExpression(Expressions.instance().createValueExpression("#{variable}"));
+      Lifecycle.beginApplication(new HashMap<String, Object>());
+      Lifecycle.mockApplication();
+      assert param.getConverter() == null;
+      Lifecycle.endApplication();
+   }
+   
+   @Test
    public void testGetValidatorById() throws ClassNotFoundException
    {
       String validatorId = "TestValidator";
       String validatorClass= "org.jboss.seam.test.unit.PageParamTest$TestValidator";
-      MockFacesContext facesContext = new MockFacesContext(new MockExternalContext(), new MockApplication());
-      facesContext.setCurrent();
+      FacesContext facesContext = setupMockFacesContextWithSeamApplication();
       facesContext.getApplication().addValidator(validatorId, validatorClass);
       Param param = new Param("param");
       param.setValidatorId(validatorId);
       assert param.getValidator() instanceof TestValidator : "expecting: " + validatorClass + "; got: " + param.getValidator();
    }
    
+   protected FacesContext setupMockFacesContextWithSeamApplication()
+   {
+      // MockApplication is wrapped with SeamApplication to validate the behavior Seam introduces
+      return new MockFacesContext(new MockExternalContext(), new SeamApplication(new MockApplication())).setCurrent();
+   }
+   
    public static class TestValidator implements Validator
    {
       public void validate(FacesContext context, UIComponent component, Object value) throws ValidatorException
       {
       }
-      
    }
 }




More information about the seam-commits mailing list