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/04/19 04:25:48 UTC

cvs commit: jakarta-tapestry/framework/src/descriptor/META-INF tapestry.url.xml

hlship      2005/04/18 19:25:48

  Modified:    .        status.xml
               src/documentation/content/xdocs/UsersGuide friendly-urls.xml
               examples/Workbench/src/context/WEB-INF web.xml
                        hivemodule.xml
               framework/src/java/org/apache/tapestry/engine/encoders
                        DirectServiceEncoder.java
               framework/src/descriptor/META-INF tapestry.url.xml
  Added:       framework/src/test/org/apache/tapestry/engine/encoders
                        TestDirectServiceEncoder.java
  Log:
  Add DirectServiceEncoder.
  
  Revision  Changes    Path
  1.88      +1 -0      jakarta-tapestry/status.xml
  
  Index: status.xml
  ===================================================================
  RCS file: /home/cvs/jakarta-tapestry/status.xml,v
  retrieving revision 1.87
  retrieving revision 1.88
  diff -u -r1.87 -r1.88
  --- status.xml	18 Apr 2005 17:22:26 -0000	1.87
  +++ status.xml	19 Apr 2005 02:25:48 -0000	1.88
  @@ -68,6 +68,7 @@
         <action type="add" dev="HLS"> Enhance listener methods, allowing them to include the request cycle optionally, and also optionally accept listener parameters. </action>
         <action type="update" dev="HLS"> Replace references to release 3.1 with release 4.0. </action>
         <action type="update" dev="HLS"> Upgrade to Javassist 3.0. </action>
  +      <action type="add" dev="HLS"> Add DirectServiceEncoder. </action>
       </release>
       <release version="3.0.3" date="Mar 26 2005">
         <action type="fix" dev="PF" fixes-bug="TAPESTRY-278"> Fixes security flaw in asset service. </action>
  
  
  
  1.1                  jakarta-tapestry/framework/src/test/org/apache/tapestry/engine/encoders/TestDirectServiceEncoder.java
  
  Index: TestDirectServiceEncoder.java
  ===================================================================
  // Copyright 2005 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.tapestry.engine.encoders;
  
  import org.apache.hivemind.test.HiveMindTestCase;
  import org.apache.tapestry.Tapestry;
  import org.apache.tapestry.engine.ServiceEncoding;
  import org.apache.tapestry.services.ServiceConstants;
  import org.easymock.MockControl;
  
  /**
   * Tests for {@link org.apache.tapestry.engine.encoders.DirectServiceEncoder}.
   * 
   * @author Howard M. Lewis Ship
   * @since 4.0
   */
  public class TestDirectServiceEncoder extends HiveMindTestCase
  {
      private ServiceEncoding newEncoding(String servletPath)
      {
          MockControl control = newControl(ServiceEncoding.class);
          ServiceEncoding encoding = (ServiceEncoding) control.getMock();
  
          encoding.getServletPath();
          control.setReturnValue(servletPath);
  
          return encoding;
      }
  
      private void train(MockControl control, ServiceEncoding encoding, String parameterName,
              String parameterValue)
      {
          encoding.getParameterValue(parameterName);
          control.setReturnValue(parameterValue);
      }
  
      public void testEncodeWrongService()
      {
          MockControl control = newControl(ServiceEncoding.class);
          ServiceEncoding encoding = (ServiceEncoding) control.getMock();
  
          train(control, encoding, ServiceConstants.SERVICE, "foo");
  
          replayControls();
  
          DirectServiceEncoder encoder = new DirectServiceEncoder();
  
          encoder.encode(encoding);
  
          verifyControls();
      }
  
      public void testEncodePageInNamespace()
      {
          MockControl control = newControl(ServiceEncoding.class);
          ServiceEncoding encoding = (ServiceEncoding) control.getMock();
  
          train(control, encoding, ServiceConstants.SERVICE, Tapestry.DIRECT_SERVICE);
          train(control, encoding, ServiceConstants.PAGE, "foo:Bar");
  
          replayControls();
  
          DirectServiceEncoder encoder = new DirectServiceEncoder();
  
          encoder.encode(encoding);
  
          verifyControls();
      }
  
      public void testEncodeStateless()
      {
          MockControl control = newControl(ServiceEncoding.class);
          ServiceEncoding encoding = (ServiceEncoding) control.getMock();
  
          train(control, encoding, ServiceConstants.SERVICE, Tapestry.DIRECT_SERVICE);
          train(control, encoding, ServiceConstants.PAGE, "admin/Menu");
          train(control, encoding, ServiceConstants.SESSION, null);
          train(control, encoding, ServiceConstants.COMPONENT, "border.link");
  
          encoding.setServletPath("/admin/Menu,border.link.direct");
          encoding.setParameterValue(ServiceConstants.SERVICE, null);
          encoding.setParameterValue(ServiceConstants.PAGE, null);
          encoding.setParameterValue(ServiceConstants.SESSION, null);
          encoding.setParameterValue(ServiceConstants.COMPONENT, null);
  
          replayControls();
  
          DirectServiceEncoder encoder = new DirectServiceEncoder();
          encoder.setStatelessExtension("direct");
  
          encoder.encode(encoding);
  
          verifyControls();
      }
  
      public void testEncodeStateful()
      {
          MockControl control = newControl(ServiceEncoding.class);
          ServiceEncoding encoding = (ServiceEncoding) control.getMock();
  
          train(control, encoding, ServiceConstants.SERVICE, Tapestry.DIRECT_SERVICE);
          train(control, encoding, ServiceConstants.PAGE, "admin/Menu");
          train(control, encoding, ServiceConstants.SESSION, "T");
          train(control, encoding, ServiceConstants.COMPONENT, "border.link");
  
          encoding.setServletPath("/admin/Menu,border.link.sdirect");
          encoding.setParameterValue(ServiceConstants.SERVICE, null);
          encoding.setParameterValue(ServiceConstants.PAGE, null);
          encoding.setParameterValue(ServiceConstants.SESSION, null);
          encoding.setParameterValue(ServiceConstants.COMPONENT, null);
  
          replayControls();
  
          DirectServiceEncoder encoder = new DirectServiceEncoder();
          encoder.setStatefulExtension("sdirect");
  
          encoder.encode(encoding);
  
          verifyControls();
      }
  
      public void testDecodeWrongExtension()
      {
          ServiceEncoding encoding = newEncoding("/foo.svc");
  
          replayControls();
  
          DirectServiceEncoder encoder = new DirectServiceEncoder();
          encoder.setStatelessExtension("direct");
          encoder.setStatefulExtension("sdirect");
  
          encoder.decode(encoding);
  
          verifyControls();
      }
  
      public void testDecodeStateless()
      {
          ServiceEncoding encoding = newEncoding("/admin/Menu,border.link.direct");
  
          encoding.setParameterValue(ServiceConstants.SERVICE, Tapestry.DIRECT_SERVICE);
          encoding.setParameterValue(ServiceConstants.PAGE, "admin/Menu");
          encoding.setParameterValue(ServiceConstants.SESSION, null);
          encoding.setParameterValue(ServiceConstants.COMPONENT, "border.link");
  
          replayControls();
  
          DirectServiceEncoder encoder = new DirectServiceEncoder();
          encoder.setStatelessExtension("direct");
          encoder.setStatefulExtension("sdirect");
  
          encoder.decode(encoding);
  
          verifyControls();
      }
      
      public void testDecodeStateful()
      {
          ServiceEncoding encoding = newEncoding("/admin/Menu,border.link.sdirect");
  
          encoding.setParameterValue(ServiceConstants.SERVICE, Tapestry.DIRECT_SERVICE);
          encoding.setParameterValue(ServiceConstants.PAGE, "admin/Menu");
          encoding.setParameterValue(ServiceConstants.SESSION, "T");
          encoding.setParameterValue(ServiceConstants.COMPONENT, "border.link");
  
          replayControls();
  
          DirectServiceEncoder encoder = new DirectServiceEncoder();
          encoder.setStatelessExtension("direct");
          encoder.setStatefulExtension("sdirect");
  
          encoder.decode(encoding);
  
          verifyControls();
      }    
  }
  
  
  1.6       +51 -10    jakarta-tapestry/src/documentation/content/xdocs/UsersGuide/friendly-urls.xml
  
  Index: friendly-urls.xml
  ===================================================================
  RCS file: /home/cvs/jakarta-tapestry/src/documentation/content/xdocs/UsersGuide/friendly-urls.xml,v
  retrieving revision 1.5
  retrieving revision 1.6
  diff -u -r1.5 -r1.6
  --- friendly-urls.xml	18 Apr 2005 17:09:03 -0000	1.5
  +++ friendly-urls.xml	19 Apr 2005 02:25:48 -0000	1.6
  @@ -61,7 +61,7 @@
       </p>
       
       <p>
  -    Friendly URLs are divided into two aspects:
  +    Friendly URLs are divided into two concerns:
       </p>
       
       <ul>
  @@ -72,7 +72,7 @@
       <p>
         For example, the ugly URL <code>/app?page=news/Thread&amp;service=page</code> may be converted into
         the friendly URL <code>/news/Threads.html</code>.  In this case, the <code>page=news/Thread</code> query parameter
  -      becamethe <code>news/Thread</code> portion of the URL, and the <code>service=page</code> query parameter
  +      became the <code>news/Thread</code> portion of the URL, and the <code>service=page</code> query parameter
         became the <code>.html</code> extension to the URL.
       </p>
       
  @@ -118,7 +118,7 @@
           
         </dt>
         <dd>
  -        Stores service parameters passed in the URL (used by &DirectLink;).
  +        Stores listener parameters passed in the URL (used by &DirectLink; and passed into &listener-method;s, the "sp" is a holdover from 3.0).
         </dd>
       </dl>
       
  @@ -189,6 +189,46 @@
       </section>
       
       <section>
  +      <title>direct-service-encoder</title>
  +      
  +      <p>A specialized encoder used <em>exclusively</em>
  +        with the direct service. Encodes the page name into the 
  +        servlet path, then a comma, then the nested id for the component.  One of two extensions
  +        is used, depending on whether the URL is stateful (an HttpSession existed when the link was rendered), or
  +        stateless.</p>
  +        
  +        <p>
  +          A typical URL might be:
  +          <code>/admin/Menu,border.link.direct</code>.  This indicates a page name of <code>admin/Menu</code> and
  +          a component id of <code>border.link</code>.  By convention, the ".direct" extension is for stateless URLs.
  +        </p>
  +        
  +        <p>The hivemodule.xml contribution:</p>
  +        
  +<source><![CDATA[
  +<contribution configuration-id="tapestry.url.ServiceEncoders">
  +  <direct-service-encoder id="direct" stateless-extension="direct" stateful-extension="sdirect"/>
  +</contribution>
  +]]></source>        
  +
  +<p>
  +  In  addition, the <code>*.direct</code> and <code>*.sdirect</code> mappings must be added to web.xml:
  +</p>
  +
  +<source><![CDATA[
  +<servlet-mapping>
  +  <servlet-name>myapp</servlet-name>
  +  <url-pattern>*.direct</url-pattern>
  +</servlet-mapping>
  +  
  +<servlet-mapping>
  +  <servlet-name>myapp</servlet-name>
  +  <url-pattern>*.sdirect</url-pattern>
  +</servlet-mapping>  ]]></source>
  +
  +    </section>
  +    
  +    <section>
         <title>asset-encoder</title>
         
         <p>
  @@ -210,9 +250,9 @@
         </p>
         
         <source><![CDATA[
  -  <contribution configuration-id="tapestry.url.ServiceEncoders">
  -    <asset-encoder id="asset" path="/assets/"/>
  -  </contribution>]]></source>
  +<contribution configuration-id="tapestry.url.ServiceEncoders">
  +  <asset-encoder id="asset" path="/assets/"/>
  +</contribution>]]></source>
         
         <p>
           This contribution will encode asset URLs using the given path.  The provided path, <code>/assets/</code> comes first,
  @@ -223,10 +263,11 @@
           In addition you must add a mapping to web.xml:
         </p>
         
  -<source><![CDATA[  <servlet-mapping>
  -    <servlet-name>myapp</servlet-name>
  -    <url-pattern>/assets/*</url-pattern>
  -  </servlet-mapping>]]></source>      
  +<source><![CDATA[
  +<servlet-mapping>
  +  <servlet-name>myapp</servlet-name>
  +  <url-pattern>/assets/*</url-pattern>
  +</servlet-mapping>]]></source>      
         
         
         <p>
  
  
  
  1.8       +10 -0     jakarta-tapestry/examples/Workbench/src/context/WEB-INF/web.xml
  
  Index: web.xml
  ===================================================================
  RCS file: /home/cvs/jakarta-tapestry/examples/Workbench/src/context/WEB-INF/web.xml,v
  retrieving revision 1.7
  retrieving revision 1.8
  diff -u -r1.7 -r1.8
  --- web.xml	12 Mar 2005 20:49:16 -0000	1.7
  +++ web.xml	19 Apr 2005 02:25:48 -0000	1.8
  @@ -48,11 +48,21 @@
     
     <servlet-mapping>
       <servlet-name>workbench</servlet-name>
  +    <url-pattern>*.external</url-pattern>
  +  </servlet-mapping>
  +    
  +  <servlet-mapping>
  +    <servlet-name>workbench</servlet-name>
       <url-pattern>*.direct</url-pattern>
     </servlet-mapping>
     
     <servlet-mapping>
       <servlet-name>workbench</servlet-name>
  +    <url-pattern>*.sdirect</url-pattern>
  +  </servlet-mapping>  
  +  
  +  <servlet-mapping>
  +    <servlet-name>workbench</servlet-name>
       <url-pattern>*.svc</url-pattern>
     </servlet-mapping>
     
  
  
  
  1.10      +2 -1      jakarta-tapestry/examples/Workbench/src/context/WEB-INF/hivemodule.xml
  
  Index: hivemodule.xml
  ===================================================================
  RCS file: /home/cvs/jakarta-tapestry/examples/Workbench/src/context/WEB-INF/hivemodule.xml,v
  retrieving revision 1.9
  retrieving revision 1.10
  diff -u -r1.9 -r1.10
  --- hivemodule.xml	25 Mar 2005 20:36:59 -0000	1.9
  +++ hivemodule.xml	19 Apr 2005 02:25:48 -0000	1.10
  @@ -23,8 +23,9 @@
     </contribution>
     
     <contribution configuration-id="tapestry.url.ServiceEncoders">
  -    <page-service-encoder id="direct" extension="direct" service="direct"/>
  +    <direct-service-encoder id="direct" stateless-extension="direct" stateful-extension="sdirect"/>
       <page-service-encoder id="page" extension="page" service="page"/>
  +    <page-service-encoder id="external" extension="external" service="external"/>    
       <asset-encoder id="asset" path="/assets/"/>
       <extension-encoder id="ext" extension="svc" after="*"/>
     </contribution>
  
  
  
  1.2       +85 -2     jakarta-tapestry/framework/src/java/org/apache/tapestry/engine/encoders/DirectServiceEncoder.java
  
  Index: DirectServiceEncoder.java
  ===================================================================
  RCS file: /home/cvs/jakarta-tapestry/framework/src/java/org/apache/tapestry/engine/encoders/DirectServiceEncoder.java,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- DirectServiceEncoder.java	18 Apr 2005 17:06:41 -0000	1.1
  +++ DirectServiceEncoder.java	19 Apr 2005 02:25:48 -0000	1.2
  @@ -1,22 +1,105 @@
  +// Copyright 2005 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.tapestry.engine.encoders;
   
  +import org.apache.tapestry.INamespace;
  +import org.apache.tapestry.Tapestry;
   import org.apache.tapestry.engine.ServiceEncoder;
   import org.apache.tapestry.engine.ServiceEncoding;
  +import org.apache.tapestry.services.ServiceConstants;
   
  -/** 
  +/**
  + * A specialized encoder for the {@link org.apache.tapestry.engine.DirectService direct service}
  + * &nbsp;that encodes the page name and component id path into the servlet path, and encodes the
  + * stateful flag by choosing one of two extensions.
    * 
    * @author Howard M. Lewis Ship
    * @since 4.0
    */
   public class DirectServiceEncoder implements ServiceEncoder
   {
  +    private String _statelessExtension;
  +
  +    private String _statefulExtension;
   
       public void encode(ServiceEncoding encoding)
       {
  +        String service = encoding.getParameterValue(ServiceConstants.SERVICE);
  +        if (!service.equals(Tapestry.DIRECT_SERVICE))
  +            return;
  +
  +        String pageName = encoding.getParameterValue(ServiceConstants.PAGE);
  +
  +        // Only handle pages in the application namespace (not from a library).
  +
  +        if (pageName.indexOf(INamespace.SEPARATOR) >= 0)
  +            return;
  +
  +        String stateful = encoding.getParameterValue(ServiceConstants.SESSION);
  +        String componentIdPath = encoding.getParameterValue(ServiceConstants.COMPONENT);
  +
  +        StringBuffer buffer = new StringBuffer("/");
  +        buffer.append(pageName);
  +
  +        buffer.append(",");
  +        buffer.append(componentIdPath);
  +
  +        buffer.append(".");
  +        buffer.append(stateful != null ? _statefulExtension : _statelessExtension);
  +
  +        encoding.setServletPath(buffer.toString());
  +
  +        encoding.setParameterValue(ServiceConstants.SERVICE, null);
  +        encoding.setParameterValue(ServiceConstants.PAGE, null);
  +        encoding.setParameterValue(ServiceConstants.SESSION, null);
  +        encoding.setParameterValue(ServiceConstants.COMPONENT, null);
       }
   
       public void decode(ServiceEncoding encoding)
       {
  +        String servletPath = encoding.getServletPath();
  +
  +        int dotx = servletPath.lastIndexOf('.');
  +        if (dotx < 0)
  +            return;
  +
  +        String extension = servletPath.substring(dotx + 1);
  +
  +        if (!(extension.equals(_statefulExtension) || extension.equals(_statelessExtension)))
  +            return;
  +
  +        int commax = servletPath.lastIndexOf(',');
  +
  +        String pageName = servletPath.substring(1, commax);
  +        String componentIdPath = servletPath.substring(commax + 1, dotx);
  +
  +        encoding.setParameterValue(ServiceConstants.SERVICE, Tapestry.DIRECT_SERVICE);
  +        encoding.setParameterValue(ServiceConstants.PAGE, pageName);
  +        encoding.setParameterValue(
  +                ServiceConstants.SESSION,
  +                extension.equals(_statefulExtension) ? "T" : null);
  +        encoding.setParameterValue(ServiceConstants.COMPONENT, componentIdPath);
       }
   
  -}
  +    public void setStatefulExtension(String statefulExtension)
  +    {
  +        _statefulExtension = statefulExtension;
  +    }
  +
  +    public void setStatelessExtension(String statelessExtension)
  +    {
  +        _statelessExtension = statelessExtension;
  +    }
  +}
  \ No newline at end of file
  
  
  
  1.15      +35 -0     jakarta-tapestry/framework/src/descriptor/META-INF/tapestry.url.xml
  
  Index: tapestry.url.xml
  ===================================================================
  RCS file: /home/cvs/jakarta-tapestry/framework/src/descriptor/META-INF/tapestry.url.xml,v
  retrieving revision 1.14
  retrieving revision 1.15
  diff -u -r1.14 -r1.15
  --- tapestry.url.xml	18 Apr 2005 17:07:50 -0000	1.14
  +++ tapestry.url.xml	19 Apr 2005 02:25:48 -0000	1.15
  @@ -72,6 +72,41 @@
           </conversion>
         </element>
         
  +      <element name="direct-service-encoder">
  +        
  +        An encoder specialized for the direct service; it encodes the page name
  +        and the component id into the servlet path, and uses one of two
  +        extensions to indicate whether the link is stateful or stateless.
  +        
  +        <attribute name="id" required="true" unique="true">
  +          Unique id for this encoder, used when ordering encoder order.
  +        </attribute>
  +        <attribute name="before">
  +          List of ids of encoders that must come before this encoder.
  +        </attribute>
  +        <attribute name="after">
  +          List of ids of encoders that must follow this encoder.
  +        </attribute>
  +        <attribute name="stateless-extension" required="true">
  +          The path extension to use for stateless links.
  +        </attribute>
  +        <attribute name="stateful-extension" required="true">
  +          The path extension to use for stateful links.
  +        </attribute>
  +        
  +        <rules>
  +          <create-object class="impl.ServiceEncoderContribution"/>
  +          <read-attribute attribute="id" property="id"/>
  +          <read-attribute attribute="before" property="before"/>
  +          <read-attribute attribute="after" property="after"/>
  +          <invoke-parent method="addElement"/>
  +          
  +          <create-object class="org.apache.tapestry.engine.encoders.DirectServiceEncoder"/>
  +          <read-attribute attribute="stateless-extension" property="statelessExtension"/>
  +          <read-attribute attribute="stateful-extension" property="statefulExtension"/>
  +          <invoke-parent method="setEncoder"/>          
  +        </rules>        
  +      </element>
         
         <element name="page-service-encoder">
           
  
  
  

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