You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@tapestry.apache.org by hl...@apache.org on 2005/06/19 17:00:46 UTC

cvs commit: jakarta-tapestry/src/documentation/content/xdocs/UsersGuide listenermethods.xml

hlship      2005/06/19 08:00:46

  Modified:    .        status.xml
               framework/src/java/org/apache/tapestry/listener
                        ListenerMapSourceImpl.java
                        ListenerMethodInvokerImpl.java
               framework/src/test/org/apache/tapestry/listener
                        TestListenerMapSource.java
                        ListenerMethodHolder.java
               src/documentation/content/xdocs index.xml
               src/documentation/content/xdocs/UsersGuide
                        listenermethods.xml
  Log:
  Listener methods may now return a page name, or a page instance, to activate and render the response.
  
  Revision  Changes    Path
  1.136     +1 -0      jakarta-tapestry/status.xml
  
  Index: status.xml
  ===================================================================
  RCS file: /home/cvs/jakarta-tapestry/status.xml,v
  retrieving revision 1.135
  retrieving revision 1.136
  diff -u -r1.135 -r1.136
  --- status.xml	17 Jun 2005 16:52:19 -0000	1.135
  +++ status.xml	19 Jun 2005 15:00:45 -0000	1.136
  @@ -84,6 +84,7 @@
          <action type="update" dev="HLS">Rework form event management to be primarily a client-side concern.</action>
          <action type="add" dev="HLS">Add translator binding prefix.</action>
          <action type="add" dev="HLS">Add cancel and refresh listener parameters to Form.</action>
  +       <action type="add" dev="HLS">Listener methods may now return a page name, or a page instance, to activate and render the response.</action>
       </release>
       <release version="4.0-alpha-3" date="May 16 2005">
         <action type="add" dev="HLS">Add initial support for the validator: binding prefix.</action>
  
  
  
  1.4       +14 -2     jakarta-tapestry/framework/src/java/org/apache/tapestry/listener/ListenerMapSourceImpl.java
  
  Index: ListenerMapSourceImpl.java
  ===================================================================
  RCS file: /home/cvs/jakarta-tapestry/framework/src/java/org/apache/tapestry/listener/ListenerMapSourceImpl.java,v
  retrieving revision 1.3
  retrieving revision 1.4
  diff -u -r1.3 -r1.4
  --- ListenerMapSourceImpl.java	10 May 2005 22:50:57 -0000	1.3
  +++ ListenerMapSourceImpl.java	19 Jun 2005 15:00:45 -0000	1.4
  @@ -25,6 +25,7 @@
   import java.util.Map;
   
   import org.apache.hivemind.util.Defense;
  +import org.apache.tapestry.IPage;
   import org.apache.tapestry.event.ResetEventListener;
   
   /**
  @@ -88,7 +89,8 @@
       private Map buildInvokerMapForClass(Class targetClass)
       {
           // map, keyed on method name, value is List of Method
  -        // only public void methods go into this map.
  +        // only methods that return void, return String, or return
  +        // something assignable to IPage are kept.
   
           Map map = new HashMap();
   
  @@ -104,7 +106,7 @@
           {
               Method m = methods[i];
   
  -            if (m.getReturnType() != void.class)
  +            if (!isAcceptibleListenerMethodReturnType(m))
                   continue;
   
               if (Modifier.isStatic(m.getModifiers()))
  @@ -118,6 +120,16 @@
           return convertMethodListMapToInvokerMap(map);
       }
   
  +    boolean isAcceptibleListenerMethodReturnType(Method m)
  +    {
  +        Class returnType = m.getReturnType();
  +
  +        if (returnType == void.class || returnType == String.class)
  +            return true;
  +
  +        return IPage.class.isAssignableFrom(returnType);
  +    }
  +
       private Map convertMethodListMapToInvokerMap(Map map)
       {
           Map result = new HashMap();
  
  
  
  1.4       +21 -3     jakarta-tapestry/framework/src/java/org/apache/tapestry/listener/ListenerMethodInvokerImpl.java
  
  Index: ListenerMethodInvokerImpl.java
  ===================================================================
  RCS file: /home/cvs/jakarta-tapestry/framework/src/java/org/apache/tapestry/listener/ListenerMethodInvokerImpl.java,v
  retrieving revision 1.3
  retrieving revision 1.4
  diff -u -r1.3 -r1.4
  --- ListenerMethodInvokerImpl.java	10 May 2005 22:50:57 -0000	1.3
  +++ ListenerMethodInvokerImpl.java	19 Jun 2005 15:00:45 -0000	1.4
  @@ -19,6 +19,7 @@
   
   import org.apache.hivemind.ApplicationRuntimeException;
   import org.apache.hivemind.util.Defense;
  +import org.apache.tapestry.IPage;
   import org.apache.tapestry.IRequestCycle;
   import org.apache.tapestry.Tapestry;
   
  @@ -148,7 +149,24 @@
   
           try
           {
  -            invokeTargetMethod(target, listenerMethod, parameters);
  +            Object methodResult = invokeTargetMethod(target, listenerMethod, parameters);
  +
  +            // void methods return null
  +
  +            if (methodResult == null)
  +                return;
  +
  +            // The method scanner, inside ListenerMapSourceImpl,
  +            // ensures that only methods that return void, String,
  +            // or assignable to IPage are considered.
  +
  +            if (methodResult instanceof String)
  +            {
  +                cycle.activate((String) methodResult);
  +                return;
  +            }
  +
  +            cycle.activate((IPage) methodResult);
           }
           catch (InvocationTargetException ex)
           {
  @@ -177,9 +195,9 @@
        * invoking the listener method.
        */
   
  -    protected void invokeTargetMethod(Object target, Method listenerMethod, Object[] parameters)
  +    protected Object invokeTargetMethod(Object target, Method listenerMethod, Object[] parameters)
               throws IllegalAccessException, InvocationTargetException
       {
  -        listenerMethod.invoke(target, parameters);
  +        return listenerMethod.invoke(target, parameters);
       }
   }
  \ No newline at end of file
  
  
  
  1.3       +73 -0     jakarta-tapestry/framework/src/test/org/apache/tapestry/listener/TestListenerMapSource.java
  
  Index: TestListenerMapSource.java
  ===================================================================
  RCS file: /home/cvs/jakarta-tapestry/framework/src/test/org/apache/tapestry/listener/TestListenerMapSource.java,v
  retrieving revision 1.2
  retrieving revision 1.3
  diff -u -r1.2 -r1.3
  --- TestListenerMapSource.java	18 Apr 2005 17:07:52 -0000	1.2
  +++ TestListenerMapSource.java	19 Jun 2005 15:00:45 -0000	1.3
  @@ -14,8 +14,11 @@
   
   package org.apache.tapestry.listener;
   
  +import java.lang.reflect.Method;
  +
   import org.apache.hivemind.ApplicationRuntimeException;
   import org.apache.hivemind.test.HiveMindTestCase;
  +import org.apache.tapestry.IPage;
   import org.apache.tapestry.IRequestCycle;
   import org.easymock.MockControl;
   
  @@ -39,6 +42,39 @@
           return cycle;
       }
   
  +    private Method findMethod(Class clazz, String name)
  +    {
  +        Method[] methods = clazz.getMethods();
  +
  +        for (int i = 0; i < methods.length; i++)
  +        {
  +            if (methods[i].getName().equals(name))
  +                return methods[i];
  +        }
  +
  +        throw new IllegalArgumentException("No method '" + name + "' in " + clazz + ".");
  +    }
  +
  +    private void attemptReturnType(boolean expected, Class clazz, String methodName)
  +    {
  +        Method m = findMethod(clazz, methodName);
  +
  +        ListenerMapSourceImpl lms = new ListenerMapSourceImpl();
  +
  +        assertEquals(expected, lms.isAcceptibleListenerMethodReturnType(m));
  +    }
  +
  +    public void testAcceptibleListenerMethodReturnTypes()
  +    {
  +        Class clazz = ListenerMethodHolder.class;
  +
  +        attemptReturnType(true, clazz, "fred");
  +        attemptReturnType(true, clazz, "returnsString");
  +        attemptReturnType(true, clazz, "returnsBasePage");
  +        attemptReturnType(false, clazz, "returnsObject");
  +        attemptReturnType(false, clazz, "returnsInt");
  +    }
  +
       public void testFoundWithParameters()
       {
           IRequestCycle cycle = newCycle(new Object[]
  @@ -120,6 +156,43 @@
           verifyControls();
       }
   
  +    public void testReturnPageName()
  +    {
  +        IRequestCycle cycle = newCycle(null);
  +        ListenerMethodHolder holder = new ListenerMethodHolder("PageName");
  +
  +        cycle.activate("PageName");
  +
  +        replayControls();
  +
  +        ListenerMapSource source = new ListenerMapSourceImpl();
  +
  +        ListenerMap map = source.getListenerMapForObject(holder);
  +
  +        map.getListener("returnsPageName").actionTriggered(null, cycle);
  +
  +        verifyControls();
  +    }
  +
  +    public void testReturnPageInstance()
  +    {
  +        IPage page = (IPage) newMock(IPage.class);
  +        IRequestCycle cycle = newCycle(null);
  +        ListenerMethodHolder holder = new ListenerMethodHolder(page);
  +
  +        cycle.activate(page);
  +
  +        replayControls();
  +
  +        ListenerMapSource source = new ListenerMapSourceImpl();
  +
  +        ListenerMap map = source.getListenerMapForObject(holder);
  +
  +        map.getListener("returnsPage").actionTriggered(null, cycle);
  +
  +        verifyControls();
  +    }
  +
       public void testNoMatch()
       {
           IRequestCycle cycle = newCycle(new Object[]
  
  
  
  1.3       +50 -0     jakarta-tapestry/framework/src/test/org/apache/tapestry/listener/ListenerMethodHolder.java
  
  Index: ListenerMethodHolder.java
  ===================================================================
  RCS file: /home/cvs/jakarta-tapestry/framework/src/test/org/apache/tapestry/listener/ListenerMethodHolder.java,v
  retrieving revision 1.2
  retrieving revision 1.3
  diff -u -r1.2 -r1.3
  --- ListenerMethodHolder.java	18 Apr 2005 17:07:52 -0000	1.2
  +++ ListenerMethodHolder.java	19 Jun 2005 15:00:45 -0000	1.3
  @@ -16,7 +16,9 @@
   
   import java.util.Map;
   
  +import org.apache.tapestry.IPage;
   import org.apache.tapestry.IRequestCycle;
  +import org.apache.tapestry.html.BasePage;
   
   /**
    * Used by {@link org.apache.tapestry.listener.TestListenerMapSource}.
  @@ -28,6 +30,24 @@
   {
       private RuntimeException _exception;
   
  +    private String _pageName;
  +
  +    private IPage _page;
  +
  +    public ListenerMethodHolder()
  +    {
  +    }
  +
  +    public ListenerMethodHolder(String pageName)
  +    {
  +        _pageName = pageName;
  +    }
  +
  +    public ListenerMethodHolder(IPage page)
  +    {
  +        _page = page;
  +    }
  +
       public void wrongTypes(Map map)
       {
       }
  @@ -46,6 +66,36 @@
   
       }
   
  +    public String returnsString()
  +    {
  +        return null;
  +    }
  +
  +    public BasePage returnsBasePage()
  +    {
  +        return null;
  +    }
  +
  +    public IPage returnsPage()
  +    {
  +        return _page;
  +    }
  +
  +    public String returnsPageName()
  +    {
  +        return _pageName;
  +    }
  +
  +    public Object returnsObject()
  +    {
  +        return null;
  +    }
  +
  +    public int returnsInt()
  +    {
  +        return 0;
  +    }
  +
       /**
        * Tapestry 3.0 and earlier style.
        */
  
  
  
  1.13      +6 -0      jakarta-tapestry/src/documentation/content/xdocs/index.xml
  
  Index: index.xml
  ===================================================================
  RCS file: /home/cvs/jakarta-tapestry/src/documentation/content/xdocs/index.xml,v
  retrieving revision 1.12
  retrieving revision 1.13
  diff -u -r1.12 -r1.13
  --- index.xml	17 Jun 2005 18:04:58 -0000	1.12
  +++ index.xml	19 Jun 2005 15:00:45 -0000	1.13
  @@ -106,6 +106,12 @@
       and leverage J2EE declarative security along the way.
     </li>
     <li>
  +    Listener methods are much easier and more flexible; listener parameters in the URL 
  +    are automatically mapped to
  +    listener method parameters, and listener methods can return the page name or page instance
  +    to activate.
  +  </li>
  +  <li>
       Component parameters now <em>just work</em>, without having to worry about
       "direction". 
     </li>
  
  
  
  1.5       +14 -7     jakarta-tapestry/src/documentation/content/xdocs/UsersGuide/listenermethods.xml
  
  Index: listenermethods.xml
  ===================================================================
  RCS file: /home/cvs/jakarta-tapestry/src/documentation/content/xdocs/UsersGuide/listenermethods.xml,v
  retrieving revision 1.4
  retrieving revision 1.5
  diff -u -r1.4 -r1.5
  --- listenermethods.xml	15 May 2005 22:56:37 -0000	1.4
  +++ listenermethods.xml	19 Jun 2005 15:00:45 -0000	1.5
  @@ -50,15 +50,22 @@
   </note>
   
   <p>
  -A listener method is a public void method. It may take parameters, or may not ... the rules are discussed below. 
  +A listener method is a public method. It may take parameters, or may not ... the rules are discussed below. 
   A simple listener method take no parameters, or takes a single parameter of type &IRequestCycle;.  
  +A listener method may return void, return a string (the name of a page), or return &IPage; (or an object 
  +assignable to &IPage;).  In
  +the latter two cases, the returned page  will be <em>activated</em> to render the response. This means that
  +in the vast majority of cases, you can write listener methods <em>without</em> the &IRequestCycle; object.
  +</p>
  +
  +<p>
   When using the &DirectLink; component, you may specify additional <em>listener parameters</em>.  The listener parameters
   are encoded into the URL and will be available in a later request, when the listener is triggered.
   </p>
   
   <note>
   In Tapestry 3.0 and earlier, <em>listener parameters</em> were known as <em>service parameters</em>.  In addition,
  -listener methods had to be in a very fixed form, taking exactly one parameter of type &IRequestCycle;.
  +listener methods had to be in a very fixed form, taking exactly one parameter of type &IRequestCycle; and returning void.
   </note>
   
   <p>
  @@ -121,14 +128,14 @@
   </p>
   
   <ul>
  -  <li>public void <em>method</em>(<em>parameters</em>)</li>
  -  <li>public void <em>method</em>(IRequestCycle cycle, <em>parameters</em>)</li>
  -  <li>public void <em>method</em>()</li>
  -  <li>public void <em>method(IRequestCycle cycle)</em></li>
  +  <li>public <em>type</em> <em>method</em>(<em>parameters</em>)</li>
  +  <li>public <em>type</em> <em>method</em>(IRequestCycle cycle, <em>parameters</em>)</li>
  +  <li>public <em>type</em> <em>method</em>()</li>
  +  <li>public <em>type</em> <em>method(IRequestCycle cycle)</em></li>
   </ul>
   
   <p>
  -Tapestry 3.0 and earlier only accepted the final variation.  Don't get too tricky with multiple overloadings
  +Tapestry 3.0 and earlier only accepted the final variation (and it had to return void).  Don't get too tricky with multiple overloadings
   of the method; Tapestry doesn't attempt to match the listener parameter types to the method parameter types (it
   works just by comparing the <em>number</em> of parameters).  However, you can count on Java boxing and autoboxing
   the parameter values (so you can use <code>int</code> and <code>java.lang.Integer</code> interchangeably).
  
  
  

---------------------------------------------------------------------
To unsubscribe, e-mail: tapestry-dev-unsubscribe@jakarta.apache.org
For additional commands, e-mail: tapestry-dev-help@jakarta.apache.org