Title: [waffle-scm] [131] trunk/core/src/main/java/org/codehaus/waffle: controller properties are now bound to the request attributes by their bean property name

Diff

Modified: trunk/core/src/main/java/org/codehaus/waffle/WaffleComponentRegistry.java (130 => 131)

--- trunk/core/src/main/java/org/codehaus/waffle/WaffleComponentRegistry.java	2007-06-02 04:16:01 UTC (rev 130)
+++ trunk/core/src/main/java/org/codehaus/waffle/WaffleComponentRegistry.java	2007-06-02 05:18:11 UTC (rev 131)
@@ -19,6 +19,7 @@
 import org.codehaus.waffle.action.MethodNameResolver;
 import org.codehaus.waffle.bind.BindErrorMessageResolver;
 import org.codehaus.waffle.bind.DataBinder;
+import org.codehaus.waffle.bind.RequestAttributeBinder;
 import org.codehaus.waffle.context.ContextContainerFactory;
 import org.codehaus.waffle.controller.ControllerDefinitionFactory;
 import org.codehaus.waffle.controller.ControllerNameResolver;
@@ -66,6 +67,8 @@
 
     Monitor getMonitor();
 
+    RequestAttributeBinder getRequestAttributeBinder();
+
     TypeConverter getTypeConverter();
 
     Validator getValidator();

Added: trunk/core/src/main/java/org/codehaus/waffle/bind/IntrospectingRequestAttributeBinder.java (0 => 131)

--- trunk/core/src/main/java/org/codehaus/waffle/bind/IntrospectingRequestAttributeBinder.java	                        (rev 0)
+++ trunk/core/src/main/java/org/codehaus/waffle/bind/IntrospectingRequestAttributeBinder.java	2007-06-02 05:18:11 UTC (rev 131)
@@ -0,0 +1,35 @@
+package org.codehaus.waffle.bind;
+
+import org.codehaus.waffle.WaffleException;
+
+import javax.servlet.http.HttpServletRequest;
+import java.beans.BeanInfo;
+import java.beans.IntrospectionException;
+import java.beans.Introspector;
+import java.beans.PropertyDescriptor;
+import java.lang.reflect.Method;
+import java.lang.reflect.InvocationTargetException;
+
+public class IntrospectingRequestAttributeBinder implements RequestAttributeBinder {
+
+    public void bind(HttpServletRequest request, Object controller) {
+        try {
+            BeanInfo beanInfo = Introspector.getBeanInfo(controller.getClass());
+            PropertyDescriptor[] propertyDescriptors = beanInfo.getPropertyDescriptors();
+
+            for (PropertyDescriptor propertyDescriptor : propertyDescriptors) {
+                Method readMethod = propertyDescriptor.getReadMethod();
+                // skip getClass() method and any get/is methods that take arguments
+                if (readMethod.getParameterTypes().length == 0 && !readMethod.getName().equals("getClass")) {
+                    request.setAttribute(propertyDescriptor.getName(), readMethod.invoke(controller));
+                }
+            }
+        } catch (IntrospectionException e) {
+            throw new WaffleException(e);
+        } catch (IllegalAccessException e) {
+            throw new WaffleException(e);
+        } catch (InvocationTargetException e) {
+            throw new WaffleException(e);
+        }
+    }
+}

Added: trunk/core/src/main/java/org/codehaus/waffle/bind/RequestAttributeBinder.java (0 => 131)

--- trunk/core/src/main/java/org/codehaus/waffle/bind/RequestAttributeBinder.java	                        (rev 0)
+++ trunk/core/src/main/java/org/codehaus/waffle/bind/RequestAttributeBinder.java	2007-06-02 05:18:11 UTC (rev 131)
@@ -0,0 +1,12 @@
+package org.codehaus.waffle.bind;
+
+import javax.servlet.http.HttpServletRequest;
+
+/**
+ * Implementors of this class allow for properties from a controller to be exposed as request attributes.  This
+ * simplifies view development.
+ */
+public interface RequestAttributeBinder {
+
+    void bind(HttpServletRequest request, Object controller);
+}

Modified: trunk/core/src/main/java/org/codehaus/waffle/context/pico/PicoWaffleComponentRegistry.java (130 => 131)

--- trunk/core/src/main/java/org/codehaus/waffle/context/pico/PicoWaffleComponentRegistry.java	2007-06-02 04:16:01 UTC (rev 130)
+++ trunk/core/src/main/java/org/codehaus/waffle/context/pico/PicoWaffleComponentRegistry.java	2007-06-02 05:18:11 UTC (rev 131)
@@ -10,12 +10,7 @@
  *****************************************************************************/
 package org.codehaus.waffle.context.pico;
 
-import java.util.Enumeration;
-
-import javax.servlet.ServletContext;
-
 import ognl.TypeConverter;
-
 import org.codehaus.waffle.WaffleComponentRegistry;
 import org.codehaus.waffle.WaffleException;
 import org.codehaus.waffle.action.ActionMethodExecutor;
@@ -33,11 +28,13 @@
 import org.codehaus.waffle.bind.DefaultBindErrorMessageResolver;
 import org.codehaus.waffle.bind.OgnlDataBinder;
 import org.codehaus.waffle.bind.OgnlTypeConverter;
+import org.codehaus.waffle.bind.RequestAttributeBinder;
+import org.codehaus.waffle.bind.IntrospectingRequestAttributeBinder;
 import org.codehaus.waffle.context.ContextContainerFactory;
+import org.codehaus.waffle.controller.ContextControllerDefinitionFactory;
+import org.codehaus.waffle.controller.ContextPathControllerNameResolver;
 import org.codehaus.waffle.controller.ControllerDefinitionFactory;
 import org.codehaus.waffle.controller.ControllerNameResolver;
-import org.codehaus.waffle.controller.ContextControllerDefinitionFactory;
-import org.codehaus.waffle.controller.ContextPathControllerNameResolver;
 import org.codehaus.waffle.i18n.DefaultMessageResources;
 import org.codehaus.waffle.i18n.MessageResources;
 import org.codehaus.waffle.monitor.ConsoleMonitor;
@@ -55,6 +52,9 @@
 import org.picocontainer.defaults.ConstructorInjectionComponentAdapter;
 import org.picocontainer.defaults.DefaultPicoContainer;
 
+import javax.servlet.ServletContext;
+import java.util.Enumeration;
+
 /**
  * PicoContainer-based implementation of WaffleComponentRegistry
  *
@@ -86,6 +86,7 @@
         register(MethodDefinitionFinder.class, AnnotatedMethodDefinitionFinder.class, servletContext);
         register(MethodNameResolver.class, RequestParameterMethodNameResolver.class, servletContext);
         register(Monitor.class, ConsoleMonitor.class, servletContext);
+        register(RequestAttributeBinder.class, IntrospectingRequestAttributeBinder.class, servletContext);
         register(TypeConverter.class, OgnlTypeConverter.class, servletContext);
         register(Validator.class, DefaultValidator.class, servletContext);
         register(ViewDispatcher.class, DefaultViewDispatcher.class, servletContext);
@@ -225,6 +226,10 @@
         return locateByType(Monitor.class);
     }
 
+    public RequestAttributeBinder getRequestAttributeBinder() {
+        return locateByType(RequestAttributeBinder.class);
+    }
+
     public TypeConverter getTypeConverter() {
         return locateByType(TypeConverter.class);
     }

Modified: trunk/core/src/main/java/org/codehaus/waffle/servlet/WaffleServlet.java (130 => 131)

--- trunk/core/src/main/java/org/codehaus/waffle/servlet/WaffleServlet.java	2007-06-02 04:16:01 UTC (rev 130)
+++ trunk/core/src/main/java/org/codehaus/waffle/servlet/WaffleServlet.java	2007-06-02 05:18:11 UTC (rev 131)
@@ -21,6 +21,7 @@
 import org.codehaus.waffle.action.MethodDefinition;
 import org.codehaus.waffle.action.MethodInvocationException;
 import org.codehaus.waffle.bind.DataBinder;
+import org.codehaus.waffle.bind.RequestAttributeBinder;
 import org.codehaus.waffle.controller.ControllerDefinition;
 import org.codehaus.waffle.controller.ControllerDefinitionFactory;
 import org.codehaus.waffle.validation.DefaultErrorsContext;
@@ -48,6 +49,7 @@
     private ActionMethodExecutor actionMethodExecutor;
     private ActionMethodResponseHandler actionMethodResponseHandler;
     private Validator validator;
+    private RequestAttributeBinder requestAttributeBinder;
     private String viewPrefix;
     private String viewSuffix;
     private boolean depsDone = false;
@@ -60,12 +62,14 @@
                          DataBinder dataBinder,
                          ActionMethodExecutor actionMethodExecutor,
                          ActionMethodResponseHandler actionMethodResponseHandler,
-                         Validator validator) {
+                         Validator validator,
+                         RequestAttributeBinder requestAttributeBinder) {
         this.controllerDefinitionFactory = controllerDefinitionFactory;
         this.dataBinder = dataBinder;
         this.actionMethodExecutor = actionMethodExecutor;
         this.actionMethodResponseHandler = actionMethodResponseHandler;
         this.validator = validator;
+        this.requestAttributeBinder = requestAttributeBinder;
         depsDone = true;
     }
 
@@ -104,7 +108,6 @@
         }
 
         return controllerDefinition;
-
     }
 
     /**
@@ -141,7 +144,7 @@
 
             // TODO ... pluggable way to register controller instance variables to the request ... no longer have to do "controller.foobar"
             // pluggable cause we need to support ognl and ruby (get_instance_variables
-
+            requestAttributeBinder.bind(request, controllerDefinition.getController());
             actionMethodResponseHandler.handle(request, response, actionMethodResponse);
         } catch (MethodInvocationException e) {
             log(e.getMessage());

Added: trunk/core/src/test/java/org/codehaus/waffle/bind/IntrospectingRequestAttributeBinderTest.java (0 => 131)

--- trunk/core/src/test/java/org/codehaus/waffle/bind/IntrospectingRequestAttributeBinderTest.java	                        (rev 0)
+++ trunk/core/src/test/java/org/codehaus/waffle/bind/IntrospectingRequestAttributeBinderTest.java	2007-06-02 05:18:11 UTC (rev 131)
@@ -0,0 +1,41 @@
+package org.codehaus.waffle.bind;
+
+import org.jmock.Expectations;
+import org.jmock.Mockery;
+import org.jmock.integration.junit4.JMock;
+import org.jmock.integration.junit4.JUnit4Mockery;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import javax.servlet.http.HttpServletRequest;
+
[EMAIL PROTECTED](JMock.class)
+public class IntrospectingRequestAttributeBinderTest {
+    private final Mockery context = new JUnit4Mockery();
+
+    @Test
+    public void allControllerPropertiesShouldBeBoundAsRequestAttributes() {
+        final HttpServletRequest request = context.mock(HttpServletRequest.class);
+
+        context.checking(new Expectations() {{
+            one (request).setAttribute("name", "my controller");
+            one (request).setAttribute("null", null);
+        }});
+
+        IntrospectingRequestAttributeBinder binder = new IntrospectingRequestAttributeBinder();
+        binder.bind(request, new SimpleController());
+    }
+
+    class SimpleController {
+        private String name = "my controller";
+
+        public String getName() {
+            return name;
+        }
+
+        public Object getNull() {
+            return null;
+        }
+    }
+
+}

Modified: trunk/core/src/test/java/org/codehaus/waffle/context/pico/PicoWaffleComponentRegistryTest.java (130 => 131)

--- trunk/core/src/test/java/org/codehaus/waffle/context/pico/PicoWaffleComponentRegistryTest.java	2007-06-02 04:16:01 UTC (rev 130)
+++ trunk/core/src/test/java/org/codehaus/waffle/context/pico/PicoWaffleComponentRegistryTest.java	2007-06-02 05:18:11 UTC (rev 131)
@@ -1,17 +1,7 @@
 package org.codehaus.waffle.context.pico;
 
-import java.lang.reflect.Field;
-import java.math.BigDecimal;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.Enumeration;
-import java.util.List;
-
-import javax.servlet.ServletContext;
-
 import ognl.DefaultTypeConverter;
 import ognl.TypeConverter;
-
 import org.codehaus.waffle.WaffleComponentRegistry;
 import org.codehaus.waffle.action.ActionMethodExecutor;
 import org.codehaus.waffle.action.ActionMethodResponseHandler;
@@ -26,12 +16,13 @@
 import org.codehaus.waffle.bind.DefaultBindErrorMessageResolver;
 import org.codehaus.waffle.bind.OgnlDataBinder;
 import org.codehaus.waffle.bind.OgnlTypeConverter;
+import org.codehaus.waffle.bind.RequestAttributeBinder;
 import org.codehaus.waffle.context.AbstractContextContainerFactory;
 import org.codehaus.waffle.context.ContextContainerFactory;
+import org.codehaus.waffle.controller.ContextControllerDefinitionFactory;
+import org.codehaus.waffle.controller.ContextPathControllerNameResolver;
 import org.codehaus.waffle.controller.ControllerDefinitionFactory;
 import org.codehaus.waffle.controller.ControllerNameResolver;
-import org.codehaus.waffle.controller.ContextControllerDefinitionFactory;
-import org.codehaus.waffle.controller.ContextPathControllerNameResolver;
 import org.codehaus.waffle.i18n.DefaultMessageResources;
 import org.codehaus.waffle.i18n.MessageResources;
 import org.codehaus.waffle.monitor.ConsoleMonitor;
@@ -52,6 +43,7 @@
 import org.codehaus.waffle.testmodel.StubValidator;
 import org.codehaus.waffle.testmodel.StubViewDispatcher;
 import org.codehaus.waffle.testmodel.StubViewResolver;
+import org.codehaus.waffle.testmodel.StubRequestAttributeBinder;
 import org.codehaus.waffle.validation.DefaultValidator;
 import org.codehaus.waffle.validation.Validator;
 import org.codehaus.waffle.view.DefaultDispatchAssistant;
@@ -64,6 +56,14 @@
 import org.jmock.MockObjectTestCase;
 import org.picocontainer.MutablePicoContainer;
 
+import javax.servlet.ServletContext;
+import java.lang.reflect.Field;
+import java.math.BigDecimal;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Enumeration;
+import java.util.List;
+
 public class PicoWaffleComponentRegistryTest extends MockObjectTestCase {
     @SuppressWarnings({"unchecked"})
     private static final Enumeration EMPTY_ENUMERATION = Collections.enumeration(Collections.EMPTY_LIST);
@@ -97,7 +97,7 @@
         mockServletContext.expects(once())
                 .method("getInitParameterNames")
                 .will(returnValue(EMPTY_ENUMERATION));
-        mockServletContext.expects(exactly(17))
+        mockServletContext.expects(exactly(18))
                 .method("getInitParameter")
                 .will(returnValue(null));
         ServletContext servletContext = (ServletContext) mockServletContext.proxy();
@@ -176,6 +176,9 @@
         mockServletContext.expects(once()).method("getInitParameter")
                 .with(eq(Monitor.class.getName()))
                 .will(returnValue(StubMonitor.class.getName()));
+        mockServletContext.expects(once()).method("getInitParameter")
+                .with(eq(RequestAttributeBinder.class.getName()))
+                .will(returnValue(StubRequestAttributeBinder.class.getName()));
 
         ServletContext servletContext = (ServletContext) mockServletContext.proxy();
         WaffleComponentRegistry componentRegistry = new PicoWaffleComponentRegistry(servletContext);
@@ -193,6 +196,7 @@
         assertTrue(componentRegistry.getActionMethodResponseHandler() instanceof StubActionMethodResponseHandler);
         assertTrue(componentRegistry.getMessageResources() instanceof StubMessageResources);
         assertTrue(componentRegistry.getMonitor() instanceof StubMonitor);
+        assertTrue(componentRegistry.getRequestAttributeBinder() instanceof StubRequestAttributeBinder);
         assertTrue(componentRegistry.getTypeConverter() instanceof DefaultTypeConverter);
         assertTrue(componentRegistry.getValidator() instanceof StubValidator);
         assertTrue(componentRegistry.getViewDispatcher() instanceof StubViewDispatcher);
@@ -207,7 +211,7 @@
         mockServletContext.expects(once())
                 .method("getInitParameterNames")
                 .will(returnValue(Collections.enumeration(names)));
-        mockServletContext.expects(exactly(17))
+        mockServletContext.expects(exactly(18))
                 .method("getInitParameter")
                 .will(returnValue(null));
         mockServletContext.expects(once())
@@ -231,7 +235,7 @@
         mockServletContext.expects(once())
                 .method("getInitParameterNames")
                 .will(returnValue(Collections.enumeration(names)));
-        mockServletContext.expects(exactly(17))
+        mockServletContext.expects(exactly(18))
                 .method("getInitParameter")
                 .will(returnValue(null));
         mockServletContext.expects(once())

Modified: trunk/core/src/test/java/org/codehaus/waffle/servlet/WaffleServletTest.java (130 => 131)

--- trunk/core/src/test/java/org/codehaus/waffle/servlet/WaffleServletTest.java	2007-06-02 04:16:01 UTC (rev 130)
+++ trunk/core/src/test/java/org/codehaus/waffle/servlet/WaffleServletTest.java	2007-06-02 05:18:11 UTC (rev 131)
@@ -10,25 +10,26 @@
  *****************************************************************************/
 package org.codehaus.waffle.servlet;
 
+import ognl.DefaultTypeConverter;
 import org.codehaus.waffle.Constants;
 import org.codehaus.waffle.WaffleComponentRegistry;
 import org.codehaus.waffle.WaffleException;
-import org.codehaus.waffle.controller.ControllerDefinition;
-import org.codehaus.waffle.controller.ControllerDefinitionFactory;
 import org.codehaus.waffle.action.ActionMethodExecutor;
 import org.codehaus.waffle.action.ActionMethodResponse;
 import org.codehaus.waffle.action.ActionMethodResponseHandler;
+import org.codehaus.waffle.action.InterceptingActionMethodExecutor;
 import org.codehaus.waffle.action.MethodDefinition;
-import org.codehaus.waffle.action.InterceptingActionMethodExecutor;
 import org.codehaus.waffle.action.MethodInvocationException;
 import org.codehaus.waffle.bind.OgnlDataBinder;
+import org.codehaus.waffle.bind.RequestAttributeBinder;
 import org.codehaus.waffle.context.RequestLevelContainer;
 import org.codehaus.waffle.context.pico.PicoContextContainer;
+import org.codehaus.waffle.controller.ControllerDefinition;
+import org.codehaus.waffle.controller.ControllerDefinitionFactory;
 import org.codehaus.waffle.testmodel.StubWaffleComponentRegistry;
 import org.codehaus.waffle.validation.ErrorsContext;
 import org.codehaus.waffle.validation.Validator;
 import org.codehaus.waffle.view.View;
-import ognl.DefaultTypeConverter;
 import org.jmock.Mock;
 import org.jmock.MockObjectTestCase;
 import org.picocontainer.defaults.DefaultPicoContainer;
@@ -102,7 +103,6 @@
                 .with(eq("org.codehaus.waffle.WaffleComponentRegistry"))
                 .will(returnValue(null));
 
-
         // Mock ServletConfig
         Mock mockServletConfig = mock(ServletConfig.class);
 
@@ -117,7 +117,7 @@
         mockServletConfig.expects(once())
                 .method("getInitParameter")
                 .with(eq(Constants.METHOD_INVOCATION_ERROR_PAGE))
-                .will(returnValue("foo.html"));        
+                .will(returnValue("foo.html"));
         final ServletConfig servletConfig = (ServletConfig) mockServletConfig.proxy();
 
         WaffleServlet servlet = new WaffleServlet() {
@@ -185,6 +185,13 @@
                 .with(isA(ControllerDefinition.class), isA(ErrorsContext.class));
         Validator validator = (Validator) mockValidator.proxy();
 
+        // Mock RequestAttributeBinder
+        Mock mockRequestAttributeBinder = mock(RequestAttributeBinder.class);
+        mockRequestAttributeBinder.expects(once())
+                .method("bind")
+                .with(same(request), isA(NonDispatchingController.class));
+        RequestAttributeBinder requestAttributeBinder = (RequestAttributeBinder) mockRequestAttributeBinder.proxy();
+
         // Set up what normally would happen via "init()"
         Field dataBinderField = WaffleServlet.class.getDeclaredField("dataBinder");
         dataBinderField.setAccessible(true);
@@ -198,6 +205,9 @@
         Field validatorFactoryField = WaffleServlet.class.getDeclaredField("validator");
         validatorFactoryField.setAccessible(true);
         validatorFactoryField.set(waffleServlet, validator);
+        Field requestAttributeBinderField = WaffleServlet.class.getDeclaredField("requestAttributeBinder");
+        requestAttributeBinderField.setAccessible(true);
+        requestAttributeBinderField.set(waffleServlet, requestAttributeBinder);
 
         waffleServlet.service(request, response);
         assertEquals(1, nonDispatchingController.getCount());
@@ -253,19 +263,6 @@
         Mock mockResponse = mock(HttpServletResponse.class);
         HttpServletResponse response = (HttpServletResponse) mockResponse.proxy();
 
-        // stub out what we don't want called ... execute it
-        WaffleServlet waffleServlet = new WaffleServlet() {
-            @Override
-            protected ControllerDefinition getControllerDefinition(HttpServletRequest request, HttpServletResponse response) {
-                return new ControllerDefinition("no name", nonDispatchingController, null);
-            }
-
-            @Override
-            public void log(String string) {
-                // ignore
-            }
-        };
-
         // Mock ActionMethodResponseHandler
         Mock mockActionMethodResponseHandler = mock(ActionMethodResponseHandler.class);
         mockActionMethodResponseHandler.expects(once())
@@ -281,19 +278,31 @@
                 .with(isA(ControllerDefinition.class), isA(ErrorsContext.class));
         Validator validator = (Validator) mockValidator.proxy();
 
-        // Set up what normally would happen via "init()"
-        Field dataBinderField = WaffleServlet.class.getDeclaredField("dataBinder");
-        dataBinderField.setAccessible(true);
-        dataBinderField.set(waffleServlet, new OgnlDataBinder(new DefaultTypeConverter(), null));
+        // Mock
+        Mock mockRequestAttributeBinder = mock(RequestAttributeBinder.class);
+        mockRequestAttributeBinder.expects(once())
+                .method("bind")
+                .with(same(request), same(nonDispatchingController));
+        RequestAttributeBinder requestAttributeBinder = (RequestAttributeBinder) mockRequestAttributeBinder.proxy();
+        
+        // stub out what we don't want called ... execute it
+        WaffleServlet waffleServlet = new WaffleServlet(null,
+                new OgnlDataBinder(new DefaultTypeConverter(), null),
+                null,
+                actionMethodResponseHandler,
+                validator,
+                requestAttributeBinder) {
+            @Override
+            protected ControllerDefinition getControllerDefinition(HttpServletRequest request, HttpServletResponse response) {
+                return new ControllerDefinition("no name", nonDispatchingController, null);
+            }
 
-        Field methodResponseHandlerField = WaffleServlet.class.getDeclaredField("actionMethodResponseHandler");
-        methodResponseHandlerField.setAccessible(true);
-        methodResponseHandlerField.set(waffleServlet, actionMethodResponseHandler);
+            @Override
+            public void log(String string) {
+                // ignore
+            }
+        };
 
-        Field validatorFactoryField = WaffleServlet.class.getDeclaredField("validator");
-        validatorFactoryField.setAccessible(true);
-        validatorFactoryField.set(waffleServlet, validator);
-
         waffleServlet.service(request, response);
     }
 

Added: trunk/core/src/test/java/org/codehaus/waffle/testmodel/StubRequestAttributeBinder.java (0 => 131)

--- trunk/core/src/test/java/org/codehaus/waffle/testmodel/StubRequestAttributeBinder.java	                        (rev 0)
+++ trunk/core/src/test/java/org/codehaus/waffle/testmodel/StubRequestAttributeBinder.java	2007-06-02 05:18:11 UTC (rev 131)
@@ -0,0 +1,10 @@
+package org.codehaus.waffle.testmodel;
+
+import org.codehaus.waffle.bind.RequestAttributeBinder;
+
+import javax.servlet.http.HttpServletRequest;
+
+public class StubRequestAttributeBinder implements RequestAttributeBinder {
+    public void bind(HttpServletRequest request, Object controller) {
+    }
+}


To unsubscribe from this list please visit:

http://xircles.codehaus.org/manage_email

Reply via email to