tapestry-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From hls...@apache.org
Subject cvs commit: jakarta-tapestry/framework/src/net/sf/tapestry/components ILinkComponent.java LinkEventType.java IServiceLink.java ServiceLinkEventType.java
Date Mon, 27 Jan 2003 16:30:24 GMT
hlship      2003/01/27 08:30:22

  Modified:    framework/src/net/sf/tapestry/link ServiceLink.jwc
                        ActionLink.jwc GenericLink.jwc ExternalLink.java
                        PageLink.java ActionLink.java DirectLink.jwc
                        ExternalLink.jwc ServiceLink.java DirectLink.java
                        PageLink.jwc GenericLink.java
               doc/src/ComponentReference GenericLink.html ActionLink.html
                        PageLink.html ExternalLink.html ServiceLink.html
                        DirectLink.html
               junit/src/net/sf/tapestry/junit TapestryTestCase.java
                        TapestrySuite.java MockEngine.java
               framework/src/net/sf/tapestry/engine RestartService.java
                        PageService.java ResetService.java
                        DirectService.java HomeService.java
                        AbstractService.java ActionService.java
                        ExternalService.java
               framework/src/net/sf/tapestry/asset AssetService.java
                        PrivateAsset.java
               examples/Tutorial/src/tutorial/workbench/chart
                        ChartService.java ChartAsset.java
               framework/src/net/sf/tapestry/html Frame.java Rollover.java
                        Shell.java
               contrib/src/net/sf/tapestry/contrib/inspector
                        ShowTemplate.java InspectorButton.java
               framework/src/net/sf/tapestry Tapestry.java
                        IEngineService.java TapestryStrings.properties
               framework/src/net/sf/tapestry/form Form.java
  Added:       framework/src/net/sf/tapestry/link DefaultLinkRenderer.java
                        ILinkRenderer.java AbstractLinkComponent.java
                        StaticLink.java
               junit/src/net/sf/tapestry/junit TestEngineServiceLink.java
                        TestStaticLink.java MockRequestCycle.java
               framework/src/net/sf/tapestry/engine ILink.java
                        EngineServiceLink.java
               framework/src/net/sf/tapestry/components ILinkComponent.java
                        LinkEventType.java
  Removed:     framework/src/net/sf/tapestry/link GestureLink.java
                        AbstractServiceLink.java
               framework/src/net/sf/tapestry Gesture.java
               framework/src/net/sf/tapestry/components IServiceLink.java
                        ServiceLinkEventType.java
  Log:
  Rework the relationship between services, link components and link rendering.
  
  Revision  Changes    Path
  1.5       +6 -10     jakarta-tapestry/framework/src/net/sf/tapestry/link/ServiceLink.jwc
  
  Index: ServiceLink.jwc
  ===================================================================
  RCS file: /home/cvs/jakarta-tapestry/framework/src/net/sf/tapestry/link/ServiceLink.jwc,v
  retrieving revision 1.4
  retrieving revision 1.5
  diff -u -r1.4 -r1.5
  --- ServiceLink.jwc	26 Jan 2003 02:59:14 -0000	1.4
  +++ ServiceLink.jwc	27 Jan 2003 16:30:10 -0000	1.5
  @@ -18,21 +18,17 @@
       as service parameters.
       </description>
     </parameter>
  -    
  +
     <parameter name="disabled"
     	java-type="boolean"
     	direction="in"/>
  -  	
  -  <parameter name="scheme" 
  +  	  	
  +  <parameter name="anchor" 
     	java-type="java.lang.String"
     	direction="in"/>
     	
  -  <parameter name="port"
  -  	java-type="int"
  -  	direction="in"/>
  -  	
  -  <parameter name="anchor" 
  -  	java-type="java.lang.String"
  +  <parameter name="renderer"
  +  	java-type="net.sf.tapestry.link.ILinkRenderer"
     	direction="in"/>
   
     <reserved-parameter name="href"/>
  
  
  
  1.4       +5 -9      jakarta-tapestry/framework/src/net/sf/tapestry/link/ActionLink.jwc
  
  Index: ActionLink.jwc
  ===================================================================
  RCS file: /home/cvs/jakarta-tapestry/framework/src/net/sf/tapestry/link/ActionLink.jwc,v
  retrieving revision 1.3
  retrieving revision 1.4
  diff -u -r1.3 -r1.4
  --- ActionLink.jwc	26 Jan 2003 02:59:14 -0000	1.3
  +++ ActionLink.jwc	27 Jan 2003 16:30:11 -0000	1.4
  @@ -19,17 +19,13 @@
     <parameter name="disabled"
     	java-type="boolean"
     	direction="in"/>
  -  	
  -  <parameter name="scheme" 
  +  	  	
  +  <parameter name="anchor" 
     	java-type="java.lang.String"
     	direction="in"/>
     	
  -  <parameter name="port"
  -  	java-type="int"
  -  	direction="in"/>
  -  	
  -  <parameter name="anchor" 
  -  	java-type="java.lang.String"
  +  <parameter name="renderer"
  +  	java-type="net.sf.tapestry.link.ILinkRenderer"
     	direction="in"/>
     	
     <parameter name="stateful" java-type="boolean" direction="custom" property-name="stateful"/>	
  
  
  
  1.7       +12 -2     jakarta-tapestry/framework/src/net/sf/tapestry/link/GenericLink.jwc
  
  Index: GenericLink.jwc
  ===================================================================
  RCS file: /home/cvs/jakarta-tapestry/framework/src/net/sf/tapestry/link/GenericLink.jwc,v
  retrieving revision 1.6
  retrieving revision 1.7
  diff -u -r1.6 -r1.7
  --- GenericLink.jwc	26 Jan 2003 02:59:14 -0000	1.6
  +++ GenericLink.jwc	27 Jan 2003 16:30:11 -0000	1.7
  @@ -12,6 +12,16 @@
     
     <parameter name="href" java-type="java.lang.String" required="yes" direction="in"/>
   
  -  <parameter name="disabled" java-type="boolean" direction="in"/>
  +  <parameter name="disabled"
  +  	java-type="boolean"
  +  	direction="in"/>
  +  	  	
  +  <parameter name="anchor" 
  +  	java-type="java.lang.String"
  +  	direction="in"/>
  +  	
  +  <parameter name="renderer"
  +  	java-type="net.sf.tapestry.link.ILinkRenderer"
  +  	direction="in"/>
     
   </component-specification>
  
  
  
  1.8       +15 -20    jakarta-tapestry/framework/src/net/sf/tapestry/link/ExternalLink.java
  
  Index: ExternalLink.java
  ===================================================================
  RCS file: /home/cvs/jakarta-tapestry/framework/src/net/sf/tapestry/link/ExternalLink.java,v
  retrieving revision 1.7
  retrieving revision 1.8
  diff -u -r1.7 -r1.8
  --- ExternalLink.java	24 Jan 2003 00:49:32 -0000	1.7
  +++ ExternalLink.java	27 Jan 2003 16:30:11 -0000	1.8
  @@ -54,9 +54,11 @@
    */
   package net.sf.tapestry.link;
   
  -import net.sf.tapestry.IEngineService;
   import net.sf.tapestry.IRequestCycle;
  +import net.sf.tapestry.RequestCycleException;
   import net.sf.tapestry.Tapestry;
  +import net.sf.tapestry.engine.EngineServiceLink;
  +import net.sf.tapestry.engine.ILink;
   
   /**
    *  A component for creating a link to {@link IExternalPage} using the 
  @@ -72,38 +74,32 @@
    *
    **/
   
  -public class ExternalLink extends GestureLink
  +public class ExternalLink extends AbstractLinkComponent
   {
       private Object _parameters;
  -
       private String _targetPage;
   
  -    /**
  -     *  Returns {@link Tapestry#EXTERNAL_SERVICE}.
  -     *
  -     **/
  -
  -    protected String getServiceName()
  +    public ILink getLink(IRequestCycle cycle) throws RequestCycleException
       {
  -        return Tapestry.EXTERNAL_SERVICE;
  +        return getLink(cycle, Tapestry.EXTERNAL_SERVICE, getServiceParameters());
       }
   
  -    protected Object[] getServiceParameters(IRequestCycle cycle)
  +    private Object[] getServiceParameters()
       {
           Object[] pageParameters = DirectLink.constructServiceParameters(_parameters);
  -        
  +
           if (pageParameters == null)
  -        return new Object[] { _targetPage  };
  -        
  +            return new Object[] { _targetPage };
  +
           Object[] parameters = new Object[pageParameters.length + 1];
  -        
  +
           parameters[0] = _targetPage;
  -        
  +
           System.arraycopy(pageParameters, 0, parameters, 1, pageParameters.length);
  -        
  +
           return parameters;
       }
  -        
  +
       public Object getParameters()
       {
           return _parameters;
  @@ -125,4 +121,3 @@
       }
   
   }
  -
  
  
  
  1.8       +6 -20     jakarta-tapestry/framework/src/net/sf/tapestry/link/PageLink.java
  
  Index: PageLink.java
  ===================================================================
  RCS file: /home/cvs/jakarta-tapestry/framework/src/net/sf/tapestry/link/PageLink.java,v
  retrieving revision 1.7
  retrieving revision 1.8
  diff -u -r1.7 -r1.8
  --- PageLink.java	24 Jan 2003 00:49:32 -0000	1.7
  +++ PageLink.java	27 Jan 2003 16:30:11 -0000	1.8
  @@ -59,6 +59,8 @@
   import net.sf.tapestry.IRequestCycle;
   import net.sf.tapestry.RequestCycleException;
   import net.sf.tapestry.Tapestry;
  +import net.sf.tapestry.engine.EngineServiceLink;
  +import net.sf.tapestry.engine.ILink;
   
   /**
    *  A component for creating a navigation link to another page, 
  @@ -71,7 +73,7 @@
    *
    **/
   
  -public class PageLink extends GestureLink
  +public class PageLink extends AbstractLinkComponent
   {
       private String _targetPage;
   
  @@ -79,23 +81,7 @@
   
       private INamespace _targetNamespace;
   
  -    /**
  -     *  Returns {@link Tapestry#PAGE_SERVICE}.
  -     *
  -     **/
  -
  -    protected String getServiceName()
  -    {
  -        return Tapestry.PAGE_SERVICE;
  -    }
  -
  -    /**
  -     *  Returns a single-element String array; the lone element is the
  -     *  name of the page, retrieved from the 'page' parameter.
  -     *
  -     **/
  -
  -    protected Object[] getServiceParameters(IRequestCycle cycle) throws RequestCycleException
  +    public ILink getLink(IRequestCycle cycle) throws RequestCycleException
       {
           String parameter = null;
   
  @@ -104,7 +90,7 @@
           else
               parameter = _targetNamespace.constructQualifiedName(_targetPage);
   
  -        return new String[] { parameter };
  +        return getLink(cycle, Tapestry.PAGE_SERVICE, new String[] { parameter });
       }
   
       public String getTargetPage()
  
  
  
  1.6       +7 -17     jakarta-tapestry/framework/src/net/sf/tapestry/link/ActionLink.java
  
  Index: ActionLink.java
  ===================================================================
  RCS file: /home/cvs/jakarta-tapestry/framework/src/net/sf/tapestry/link/ActionLink.java,v
  retrieving revision 1.5
  retrieving revision 1.6
  diff -u -r1.5 -r1.6
  --- ActionLink.java	24 Jan 2003 00:49:32 -0000	1.5
  +++ ActionLink.java	27 Jan 2003 16:30:11 -0000	1.6
  @@ -61,6 +61,8 @@
   import net.sf.tapestry.RenderRewoundException;
   import net.sf.tapestry.RequestCycleException;
   import net.sf.tapestry.Tapestry;
  +import net.sf.tapestry.engine.EngineServiceLink;
  +import net.sf.tapestry.engine.ILink;
   
   /**
    *  A component for creating a link that is handled using the action service.
  @@ -73,7 +75,7 @@
    *
    **/
   
  -public class ActionLink extends GestureLink implements IAction
  +public class ActionLink extends AbstractLinkComponent implements IAction
   {
       private IActionListener _listener;
       private IBinding _statefulBinding;
  @@ -98,21 +100,9 @@
           return _statefulBinding.getBoolean();
       }
   
  -    /**
  -     *  Returns {@link Tapestry#ACTION_SERVICE}.
  -     * 
  -     **/
  -
  -    protected String getServiceName()
  +    public ILink getLink(IRequestCycle cycle) throws RequestCycleException
       {
  -        return Tapestry.ACTION_SERVICE;
  -    }
  -
  -    protected Object[] getServiceParameters(IRequestCycle cycle) throws RequestCycleException
  -    {
  -        String actionId;
  -
  -        actionId = cycle.getNextActionId();
  +        String actionId = cycle.getNextActionId();
   
           if (cycle.isRewound(this))
           {
  @@ -121,7 +111,7 @@
               throw new RenderRewoundException(this);
           }
   
  -        return new Object[] { actionId };
  +        return getLink(cycle, Tapestry.ACTION_SERVICE, new Object[] { actionId });
       }
   
       public IBinding getStatefulBinding()
  
  
  
  1.5       +5 -9      jakarta-tapestry/framework/src/net/sf/tapestry/link/DirectLink.jwc
  
  Index: DirectLink.jwc
  ===================================================================
  RCS file: /home/cvs/jakarta-tapestry/framework/src/net/sf/tapestry/link/DirectLink.jwc,v
  retrieving revision 1.4
  retrieving revision 1.5
  diff -u -r1.4 -r1.5
  --- DirectLink.jwc	26 Jan 2003 02:59:14 -0000	1.4
  +++ DirectLink.jwc	27 Jan 2003 16:30:11 -0000	1.5
  @@ -28,17 +28,13 @@
     <parameter name="disabled"
     	java-type="boolean"
     	direction="in"/>
  -  	
  -  <parameter name="scheme" 
  +  	  	
  +  <parameter name="anchor" 
     	java-type="java.lang.String"
     	direction="in"/>
     	
  -  <parameter name="port"
  -  	java-type="int"
  -  	direction="in"/>
  -  	
  -  <parameter name="anchor" 
  -  	java-type="java.lang.String"
  +  <parameter name="renderer"
  +  	java-type="net.sf.tapestry.link.ILinkRenderer"
     	direction="in"/>
     
     <reserved-parameter name="href"/>
  
  
  
  1.5       +5 -5      jakarta-tapestry/framework/src/net/sf/tapestry/link/ExternalLink.jwc
  
  Index: ExternalLink.jwc
  ===================================================================
  RCS file: /home/cvs/jakarta-tapestry/framework/src/net/sf/tapestry/link/ExternalLink.jwc,v
  retrieving revision 1.4
  retrieving revision 1.5
  diff -u -r1.4 -r1.5
  --- ExternalLink.jwc	26 Jan 2003 02:59:14 -0000	1.4
  +++ ExternalLink.jwc	27 Jan 2003 16:30:11 -0000	1.5
  @@ -24,13 +24,13 @@
     <parameter name="disabled"
     	java-type="boolean"
     	direction="in"/>
  -  	
  -  <parameter name="scheme" 
  +  	  	
  +  <parameter name="anchor" 
     	java-type="java.lang.String"
     	direction="in"/>
     	
  -  <parameter name="port"
  -  	java-type="int"
  +  <parameter name="renderer"
  +  	java-type="net.sf.tapestry.link.ILinkRenderer"
     	direction="in"/>
     	
     <reserved-parameter name="href"/>
  
  
  
  1.8       +8 -20     jakarta-tapestry/framework/src/net/sf/tapestry/link/ServiceLink.java
  
  Index: ServiceLink.java
  ===================================================================
  RCS file: /home/cvs/jakarta-tapestry/framework/src/net/sf/tapestry/link/ServiceLink.java,v
  retrieving revision 1.7
  retrieving revision 1.8
  diff -u -r1.7 -r1.8
  --- ServiceLink.java	13 Jan 2003 03:33:07 -0000	1.7
  +++ ServiceLink.java	27 Jan 2003 16:30:11 -0000	1.8
  @@ -55,6 +55,9 @@
   package net.sf.tapestry.link;
   
   import net.sf.tapestry.IRequestCycle;
  +import net.sf.tapestry.RequestCycleException;
  +import net.sf.tapestry.engine.EngineServiceLink;
  +import net.sf.tapestry.engine.ILink;
   
   /**
    *  A component for creating a link for an arbitrary {@link net.sf.tapestry.IEngineService
  @@ -69,31 +72,16 @@
    *
    **/
   
  -public class ServiceLink extends GestureLink
  +public class ServiceLink extends AbstractLinkComponent
   {
       private String _service;
       private Object _parameters;
   
  -
  -    /**
  -     *  Returns name of the service specified by the service parameter.
  -     **/
  -
  -    protected String getServiceName()
  -    {
  -        return _service;
  -    }
  -
  -    /** 
  -     *  Invokes {@link DirectLink#constructContext(Object)} to create Object[]
  -     *  from the context parameter (which may be an object, array of Strings or List of Strings).
  -     * 
  -     **/
  -
  -    protected Object[] getServiceParameters(IRequestCycle cycle)
  +    public ILink getLink(IRequestCycle cycle) throws RequestCycleException
       {
  -        return DirectLink.constructServiceParameters(_parameters);
  +        Object[] parameters = DirectLink.constructServiceParameters(_parameters);
   
  +        return getLink(cycle, _service, parameters);
       }
   
       public String getService()
  
  
  
  1.9       +9 -14     jakarta-tapestry/framework/src/net/sf/tapestry/link/DirectLink.java
  
  Index: DirectLink.java
  ===================================================================
  RCS file: /home/cvs/jakarta-tapestry/framework/src/net/sf/tapestry/link/DirectLink.java,v
  retrieving revision 1.8
  retrieving revision 1.9
  diff -u -r1.8 -r1.9
  --- DirectLink.java	24 Jan 2003 00:49:32 -0000	1.8
  +++ DirectLink.java	27 Jan 2003 16:30:11 -0000	1.9
  @@ -64,6 +64,8 @@
   import net.sf.tapestry.RequestCycleException;
   import net.sf.tapestry.RequiredParameterException;
   import net.sf.tapestry.Tapestry;
  +import net.sf.tapestry.engine.EngineServiceLink;
  +import net.sf.tapestry.engine.ILink;
   
   /**
    *  A component for creating a link using the direct service; used for actions that
  @@ -76,7 +78,7 @@
    *
    **/
   
  -public class DirectLink extends GestureLink implements IDirect
  +public class DirectLink extends AbstractLinkComponent implements IDirect
   {
       private IBinding _listenerBinding;
       private Object _parameters;
  @@ -107,19 +109,12 @@
           return _statefulBinding.getBoolean();
       }
   
  -    /**
  -     *  Returns {@link net.sf.tapestry.Tapestry#DIRECT_SERVICE}.
  -     *
  -     **/
  -
  -    protected String getServiceName()
  -    {
  -        return Tapestry.DIRECT_SERVICE;
  -    }
  -
  -    protected Object[] getServiceParameters(IRequestCycle cycle)
  +    public ILink getLink(IRequestCycle cycle) throws RequestCycleException
       {
  -        return constructServiceParameters(_parameters);
  +        return getLink(
  +            cycle,
  +            Tapestry.DIRECT_SERVICE,
  +            constructServiceParameters(_parameters));
       }
   
       /**
  
  
  
  1.4       +5 -9      jakarta-tapestry/framework/src/net/sf/tapestry/link/PageLink.jwc
  
  Index: PageLink.jwc
  ===================================================================
  RCS file: /home/cvs/jakarta-tapestry/framework/src/net/sf/tapestry/link/PageLink.jwc,v
  retrieving revision 1.3
  retrieving revision 1.4
  diff -u -r1.3 -r1.4
  --- PageLink.jwc	26 Jan 2003 02:59:14 -0000	1.3
  +++ PageLink.jwc	27 Jan 2003 16:30:11 -0000	1.4
  @@ -25,17 +25,13 @@
     <parameter name="disabled"
     	java-type="boolean"
     	direction="in"/>
  -  	
  -  <parameter name="scheme" 
  +  	  	
  +  <parameter name="anchor" 
     	java-type="java.lang.String"
     	direction="in"/>
     	
  -  <parameter name="port"
  -  	java-type="int"
  -  	direction="in"/>
  -  	
  -  <parameter name="anchor" 
  -  	java-type="java.lang.String"
  +  <parameter name="renderer"
  +  	java-type="net.sf.tapestry.link.ILinkRenderer"
     	direction="in"/>
     
     <reserved-parameter name="href"/>
  
  
  
  1.9       +11 -18    jakarta-tapestry/framework/src/net/sf/tapestry/link/GenericLink.java
  
  Index: GenericLink.java
  ===================================================================
  RCS file: /home/cvs/jakarta-tapestry/framework/src/net/sf/tapestry/link/GenericLink.java,v
  retrieving revision 1.8
  retrieving revision 1.9
  diff -u -r1.8 -r1.9
  --- GenericLink.java	13 Jan 2003 03:33:07 -0000	1.8
  +++ GenericLink.java	27 Jan 2003 16:30:11 -0000	1.9
  @@ -56,9 +56,10 @@
   
   import net.sf.tapestry.IRequestCycle;
   import net.sf.tapestry.RequestCycleException;
  +import net.sf.tapestry.engine.ILink;
   
   /**
  - *  An implementation of {@link net.sf.tapestry.components.IServiceLink} 
  + *  An implementation of {@link net.sf.tapestry.components.ILinkComponent} 
    *  that allows
    *  the exact HREF to be specified, usually used for client side
    *  scripting.  
  @@ -72,31 +73,23 @@
    * 
    **/
   
  -public class GenericLink extends AbstractServiceLink
  +public class GenericLink extends AbstractLinkComponent
   {
  -    private String href;
  +    private String _href;
   
  -    /**
  -     *  Returns the String specified by the href binding (this method is invoked
  -     *  while renderring).
  -     * 
  -     *  @throws RequiredParameterException if no href value was supplied.
  -     * 
  -     **/
  -
  -    protected String getURL(IRequestCycle cycle) throws RequestCycleException
  +    public String getHref()
       {
  -        return href;
  +        return _href;
       }
   
  -    public String getHref()
  +    public void setHref(String href)
       {
  -        return href;
  +        _href = href;
       }
   
  -    public void setHref(String href)
  +    public ILink getLink(IRequestCycle cycle) throws RequestCycleException
       {
  -        this.href = href;
  +        return new StaticLink(_href);
       }
   
   }
  
  
  
  1.1                  jakarta-tapestry/framework/src/net/sf/tapestry/link/DefaultLinkRenderer.java
  
  Index: DefaultLinkRenderer.java
  ===================================================================
  /*
   *  ====================================================================
   *  The Apache Software License, Version 1.1
   *
   *  Copyright (c) 2002 The Apache Software Foundation.  All rights
   *  reserved.
   *
   *  Redistribution and use in source and binary forms, with or without
   *  modification, are permitted provided that the following conditions
   *  are met:
   *
   *  1. Redistributions of source code must retain the above copyright
   *  notice, this list of conditions and the following disclaimer.
   *
   *  2. Redistributions in binary form must reproduce the above copyright
   *  notice, this list of conditions and the following disclaimer in
   *  the documentation and/or other materials provided with the
   *  distribution.
   *
   *  3. The end-user documentation included with the redistribution,
   *  if any, must include the following acknowledgment:
   *  "This product includes software developed by the
   *  Apache Software Foundation (http://www.apache.org/)."
   *  Alternately, this acknowledgment may appear in the software itself,
   *  if and wherever such third-party acknowledgments normally appear.
   *
   *  4. The names "Apache" and "Apache Software Foundation" and
   *  "Apache Tapestry" must not be used to endorse or promote products
   *  derived from this software without prior written permission. For
   *  written permission, please contact apache@apache.org.
   *
   *  5. Products derived from this software may not be called "Apache",
   *  "Apache Tapestry", nor may "Apache" appear in their name, without
   *  prior written permission of the Apache Software Foundation.
   *
   *  THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   *  WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   *  OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   *  DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   *  ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   *  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   *  USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   *  ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   *  OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   *  OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   *  SUCH DAMAGE.
   *  ====================================================================
   *
   *  This software consists of voluntary contributions made by many
   *  individuals on behalf of the Apache Software Foundation.  For more
   *  information on the Apache Software Foundation, please see
   *  <http://www.apache.org/>.
   */
  package net.sf.tapestry.link;
  
  import net.sf.tapestry.IMarkupWriter;
  import net.sf.tapestry.IRequestCycle;
  import net.sf.tapestry.RequestCycleException;
  import net.sf.tapestry.Tapestry;
  import net.sf.tapestry.components.ILinkComponent;
  import net.sf.tapestry.engine.EngineServiceLink;
  import net.sf.tapestry.engine.ILink;
  
  /**
   *  Default implementation of {@link net.sf.tapestry.link.ILinkRenderer}, which
   *  does nothing special.  Can be used as a base class to provide
   *  additional handling.
   *
   *  @author Howard Lewis Ship
   *  @version $Id: DefaultLinkRenderer.java,v 1.1 2003/01/27 16:30:11 hlship Exp $
   *  @since 2.4
   **/
  
  public class DefaultLinkRenderer implements ILinkRenderer
  {
      /**
       *  A shared instance used as a default for any link that doesn't explicitly
       *  override.
       * 
       **/
  
      public static final ILinkRenderer SHARED_INSTANCE = new DefaultLinkRenderer();
  
      public void renderLink(IMarkupWriter writer, IRequestCycle cycle, ILinkComponent linkComponent)
          throws RequestCycleException
      {
          IMarkupWriter wrappedWriter = null;
  
          if (cycle.getAttribute(Tapestry.LINK_COMPONENT_ATTRIBUTE_NAME) != null)
              throw new RequestCycleException(
                  Tapestry.getString("AbstractLinkComponent.no-nesting"),
                  linkComponent);
  
          cycle.setAttribute(Tapestry.LINK_COMPONENT_ATTRIBUTE_NAME, linkComponent);
  
          boolean disabled = linkComponent.isDisabled();
  
          if (!disabled)
          {
             ILink l = linkComponent.getLink(cycle);
  
              writer.begin("a");
              writer.attribute("href", constructURL(l, cycle));
  
              beforeBodyRender(writer, cycle, linkComponent);
  
              // Allow the wrapped components a chance to render.
              // Along the way, they may interact with this component
              // and cause the name variable to get set.
  
              wrappedWriter = writer.getNestedWriter();
          }
          else
              wrappedWriter = writer;
  
          linkComponent.renderBody(wrappedWriter, cycle);
  
          if (!disabled)
          {
              afterBodyRender(writer, cycle, linkComponent);
  
              linkComponent.renderAdditionalAttributes(writer, cycle);
  
              wrappedWriter.close();
  
              // Close the <a> tag
  
              writer.end();
          }
  
          cycle.removeAttribute(Tapestry.LINK_COMPONENT_ATTRIBUTE_NAME);
      }
  
      /**
       *  Converts the EngineServiceLink into a URI or URL.  This implementation
       *  simply invokes {@link net.sf.tapestry.EngineServiceLink#getURL()}.
       * 
       **/
  
      protected String constructURL(ILink link, IRequestCycle cycle)
      {
          return link.getURL();
      }
  
      /**
       *  Invoked after the href attribute has been written but before
       *  the body of the link is rendered (but only if the link
       *  is not disabled).
       * 
       *  <p>
       *  This implementation does nothing.
       * 
       **/
  
      protected void beforeBodyRender(IMarkupWriter writer, IRequestCycle cycle, ILinkComponent link)
      {
      }
  
      /**
       *  Invoked after the body of the link is rendered, but before
       *  {@link ILinkComponent#renderAdditionalAttributes(IMarkupWriter, IRequestCycle)} is invoked
       *  (but only if the link is not disabled).
       * 
       *  <p>
       *  This implementation does nothing.
       * 
       **/
  
      protected void afterBodyRender(IMarkupWriter writer, IRequestCycle cycle, ILinkComponent link)
      {
      }
  }
  
  
  
  1.1                  jakarta-tapestry/framework/src/net/sf/tapestry/link/ILinkRenderer.java
  
  Index: ILinkRenderer.java
  ===================================================================
  /*
   *  ====================================================================
   *  The Apache Software License, Version 1.1
   *
   *  Copyright (c) 2002 The Apache Software Foundation.  All rights
   *  reserved.
   *
   *  Redistribution and use in source and binary forms, with or without
   *  modification, are permitted provided that the following conditions
   *  are met:
   *
   *  1. Redistributions of source code must retain the above copyright
   *  notice, this list of conditions and the following disclaimer.
   *
   *  2. Redistributions in binary form must reproduce the above copyright
   *  notice, this list of conditions and the following disclaimer in
   *  the documentation and/or other materials provided with the
   *  distribution.
   *
   *  3. The end-user documentation included with the redistribution,
   *  if any, must include the following acknowledgment:
   *  "This product includes software developed by the
   *  Apache Software Foundation (http://www.apache.org/)."
   *  Alternately, this acknowledgment may appear in the software itself,
   *  if and wherever such third-party acknowledgments normally appear.
   *
   *  4. The names "Apache" and "Apache Software Foundation" and
   *  "Apache Tapestry" must not be used to endorse or promote products
   *  derived from this software without prior written permission. For
   *  written permission, please contact apache@apache.org.
   *
   *  5. Products derived from this software may not be called "Apache",
   *  "Apache Tapestry", nor may "Apache" appear in their name, without
   *  prior written permission of the Apache Software Foundation.
   *
   *  THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   *  WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   *  OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   *  DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   *  ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   *  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   *  USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   *  ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   *  OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   *  OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   *  SUCH DAMAGE.
   *  ====================================================================
   *
   *  This software consists of voluntary contributions made by many
   *  individuals on behalf of the Apache Software Foundation.  For more
   *  information on the Apache Software Foundation, please see
   *  <http://www.apache.org/>.
   */
  package net.sf.tapestry.link;
  
  import net.sf.tapestry.IMarkupWriter;
  import net.sf.tapestry.IRequestCycle;
  import net.sf.tapestry.RequestCycleException;
  import net.sf.tapestry.components.ILinkComponent;
  import net.sf.tapestry.engine.EngineServiceLink;
  
  /**
   *  Used by various instances of {@link net.sf.tapestry.components.ILinkComponent} to
   *  actually renderer a link.  Implementations of the interface can manipulate
   *  some of the details of how the link is written.
   * 
   *  <p>
   *  A link rendered may be used in many threads, and must be threadsafe.
   *
   *  @author Howard Lewis Ship
   *  @version $Id: ILinkRenderer.java,v 1.1 2003/01/27 16:30:11 hlship Exp $
   *  @since 2.4
   * 
   **/
  
  public interface ILinkRenderer
  {
      /**
       *  Renders the link, taking into account whether the link is
       *  {@link net.sf.tapestry.components.ILinkComponent#isDisabled() disabled}.
       *  This is complicated by the fact that the rendering of the body must be done
       *  within a nested writer, since the Link component will not render its tag
       *  until after its body renders (to allow for any wrapped components that need
       *  to write event handlers for the link).
       * 
       *  <p>
       *  The renderer is expected to call back into the link component to handle
       *  any informal parameters, and to handle events output.\
       * 
       * 
       **/
  
      public void renderLink(
          IMarkupWriter writer,
          IRequestCycle cycle,
          ILinkComponent linkComponent)
          throws RequestCycleException;
  
  }
  
  
  
  1.1                  jakarta-tapestry/framework/src/net/sf/tapestry/link/AbstractLinkComponent.java
  
  Index: AbstractLinkComponent.java
  ===================================================================
  /*
   *  ====================================================================
   *  The Apache Software License, Version 1.1
   *
   *  Copyright (c) 2002 The Apache Software Foundation.  All rights
   *  reserved.
   *
   *  Redistribution and use in source and binary forms, with or without
   *  modification, are permitted provided that the following conditions
   *  are met:
   *
   *  1. Redistributions of source code must retain the above copyright
   *  notice, this list of conditions and the following disclaimer.
   *
   *  2. Redistributions in binary form must reproduce the above copyright
   *  notice, this list of conditions and the following disclaimer in
   *  the documentation and/or other materials provided with the
   *  distribution.
   *
   *  3. The end-user documentation included with the redistribution,
   *  if any, must include the following acknowledgment:
   *  "This product includes software developed by the
   *  Apache Software Foundation (http://www.apache.org/)."
   *  Alternately, this acknowledgment may appear in the software itself,
   *  if and wherever such third-party acknowledgments normally appear.
   *
   *  4. The names "Apache" and "Apache Software Foundation" and
   *  "Apache Tapestry" must not be used to endorse or promote products
   *  derived from this software without prior written permission. For
   *  written permission, please contact apache@apache.org.
   *
   *  5. Products derived from this software may not be called "Apache",
   *  "Apache Tapestry", nor may "Apache" appear in their name, without
   *  prior written permission of the Apache Software Foundation.
   *
   *  THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   *  WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   *  OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   *  DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   *  ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   *  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   *  USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   *  ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   *  OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   *  OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   *  SUCH DAMAGE.
   *  ====================================================================
   *
   *  This software consists of voluntary contributions made by many
   *  individuals on behalf of the Apache Software Foundation.  For more
   *  information on the Apache Software Foundation, please see
   *  <http://www.apache.org/>.
   */
  package net.sf.tapestry.link;
  
  import java.util.ArrayList;
  import java.util.HashMap;
  import java.util.Iterator;
  import java.util.List;
  import java.util.Map;
  
  import net.sf.tapestry.AbstractComponent;
  import net.sf.tapestry.IEngineService;
  import net.sf.tapestry.IMarkupWriter;
  import net.sf.tapestry.IRequestCycle;
  import net.sf.tapestry.RequestCycleException;
  import net.sf.tapestry.Tapestry;
  import net.sf.tapestry.components.ILinkComponent;
  import net.sf.tapestry.components.LinkEventType;
  import net.sf.tapestry.engine.EngineServiceLink;
  import net.sf.tapestry.engine.ILink;
  import net.sf.tapestry.html.Body;
  
  /**
   *  Base class for
   *  implementations of {@link ILinkComponent}.  Includes a disabled attribute
   *  (that should be bound to a disabled parameter), 
   *  an anchor attribute, and a
   *  renderer attribute (that should be bound to a renderer parameter).  A default,
   *  shared instance of {@link net.sf.tapestry.link.DefaultLinkRenderer} is
   *  used when no specific renderer is provided.
   *
   *  @author Howard Lewis Ship
   *  @version $Id: AbstractLinkComponent.java,v 1.1 2003/01/27 16:30:11 hlship Exp $
   *
   **/
  
  public abstract class AbstractLinkComponent extends AbstractComponent implements ILinkComponent
  {
      private boolean _disabled;
      private ILinkRenderer _renderer = DefaultLinkRenderer.SHARED_INSTANCE;
      private String _anchor;
  
      private Map _eventHandlers;
  
      public boolean isDisabled()
      {
          return _disabled;
      }
  
      public void setDisabled(boolean disabled)
      {
          _disabled = disabled;
      }
  
      /**
       *  Adds an event handler (typically, from a wrapped component such
       *  as a {@link net.sf.tapestry.html.Rollover}).
       *
       **/
  
      public void addEventHandler(LinkEventType eventType, String functionName)
      {
          Object currentValue;
  
          if (_eventHandlers == null)
              _eventHandlers = new HashMap();
  
          currentValue = _eventHandlers.get(eventType);
  
          // The first value is added as a String
  
          if (currentValue == null)
          {
              _eventHandlers.put(eventType, functionName);
              return;
          }
  
          // When adding the second value, convert to a List
  
          if (currentValue instanceof String)
          {
              List list = new ArrayList();
              list.add(currentValue);
              list.add(functionName);
  
              _eventHandlers.put(eventType, list);
              return;
          }
  
          // For the third and up, add the new function to the List
  
          List list = (List) currentValue;
          list.add(functionName);
      }
  
      /**
       *  Renders the link by delegating to an instance
       *  of {@link ILinkRenderer}.
       *
       **/
  
      protected void renderComponent(IMarkupWriter writer, IRequestCycle cycle)
          throws RequestCycleException
      {
          _renderer.renderLink(writer, cycle, this);
      }
  
      protected void cleanupAfterRender(IRequestCycle cycle)
      {
          _eventHandlers = null;
  
          super.cleanupAfterRender(cycle);
      }
  
      protected void writeEventHandlers(IMarkupWriter writer, IRequestCycle cycle)
          throws RequestCycleException
      {
          String name = null;
  
          if (_eventHandlers == null)
              return;
  
          Body body = Body.get(cycle);
  
          if (body == null)
              throw new RequestCycleException(
                  Tapestry.getString("AbstractLinkComponent.events-need-body"),
                  this);
  
          Iterator i = _eventHandlers.entrySet().iterator();
  
          while (i.hasNext())
          {
              Map.Entry entry = (Map.Entry) i.next();
              LinkEventType type = (LinkEventType) entry.getKey();
  
              name = writeEventHandler(writer, body, name, type.getAttributeName(), entry.getValue());
          }
  
      }
  
      protected String writeEventHandler(
          IMarkupWriter writer,
          Body body,
          String name,
          String attributeName,
          Object value)
          throws RequestCycleException
      {
          String wrapperFunctionName;
  
          if (value instanceof String)
          {
              wrapperFunctionName = (String) value;
          }
          else
          {
              if (name == null)
                  name = "Link" + body.getUniqueId();
  
              wrapperFunctionName = attributeName + "_" + name;
  
              StringBuffer buffer = new StringBuffer();
  
              buffer.append("function ");
              buffer.append(wrapperFunctionName);
              buffer.append(" ()\n{\n");
  
              Iterator i = ((List) value).iterator();
              while (i.hasNext())
              {
                  String functionName = (String) i.next();
                  buffer.append("  ");
                  buffer.append(functionName);
                  buffer.append("();\n");
              }
  
              buffer.append("}\n\n");
  
              body.addOtherScript(buffer.toString());
          }
  
          writer.attribute(attributeName, "javascript:" + wrapperFunctionName + "();");
  
          return name;
      }
  
      /** @since 2.4 **/
  
      public ILinkRenderer getRenderer()
      {
          return _renderer;
      }
  
      /** @since 2.4 **/
  
      public void setRenderer(ILinkRenderer renderer)
      {
          _renderer = renderer;
      }
  
      public void renderAdditionalAttributes(IMarkupWriter writer, IRequestCycle cycle)
          throws RequestCycleException
      {
          writeEventHandlers(writer, cycle);
  
          // Generate additional attributes from informal parameters.
  
          generateAttributes(writer, cycle);
      }
  
      /**
       *  Utility method for subclasses; Gets the named service from the engine
       *  and invokes {@link net.sf.tapestry.IEngineService#buildGesture(IRequestCycle, IComponent, Object[])}
       *  on it.
       * 
       *  @since 2.4
       * 
       **/
  
      protected ILink getLink(
          IRequestCycle cycle,
          String serviceName,
          Object[] serviceParameters)
      {
          IEngineService service = cycle.getEngine().getService(serviceName);
  
          return service.getLink(cycle, this, serviceParameters);
      }
      
      public String getAnchor()
      {
          return _anchor;
      }
  
      public void setAnchor(String anchor)
      {
          _anchor = anchor;
      }
  
  }
  
  
  1.1                  jakarta-tapestry/framework/src/net/sf/tapestry/link/StaticLink.java
  
  Index: StaticLink.java
  ===================================================================
  /*
   *  ====================================================================
   *  The Apache Software License, Version 1.1
   *
   *  Copyright (c) 2002 The Apache Software Foundation.  All rights
   *  reserved.
   *
   *  Redistribution and use in source and binary forms, with or without
   *  modification, are permitted provided that the following conditions
   *  are met:
   *
   *  1. Redistributions of source code must retain the above copyright
   *  notice, this list of conditions and the following disclaimer.
   *
   *  2. Redistributions in binary form must reproduce the above copyright
   *  notice, this list of conditions and the following disclaimer in
   *  the documentation and/or other materials provided with the
   *  distribution.
   *
   *  3. The end-user documentation included with the redistribution,
   *  if any, must include the following acknowledgment:
   *  "This product includes software developed by the
   *  Apache Software Foundation (http://www.apache.org/)."
   *  Alternately, this acknowledgment may appear in the software itself,
   *  if and wherever such third-party acknowledgments normally appear.
   *
   *  4. The names "Apache" and "Apache Software Foundation" and
   *  "Apache Tapestry" must not be used to endorse or promote products
   *  derived from this software without prior written permission. For
   *  written permission, please contact apache@apache.org.
   *
   *  5. Products derived from this software may not be called "Apache",
   *  "Apache Tapestry", nor may "Apache" appear in their name, without
   *  prior written permission of the Apache Software Foundation.
   *
   *  THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   *  WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   *  OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   *  DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   *  ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   *  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   *  USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   *  ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   *  OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   *  OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   *  SUCH DAMAGE.
   *  ====================================================================
   *
   *  This software consists of voluntary contributions made by many
   *  individuals on behalf of the Apache Software Foundation.  For more
   *  information on the Apache Software Foundation, please see
   *  <http://www.apache.org/>.
   */
  package net.sf.tapestry.link;
  
  import net.sf.tapestry.engine.ILink;
  
  /**
   *  Used by {@link net.sf.tapestry.link.GenericLink} to represent
   *  an external, static URL.
   *
   *  @author Howard Lewis Ship
   *  @version $Id: StaticLink.java,v 1.1 2003/01/27 16:30:11 hlship Exp $
   *  @since 2.4
   * 
   **/
  public class StaticLink implements ILink
  {
  	private String _url;
  
  	public StaticLink(String url)
  	{
  		_url = url;
  	}
  
      public String getURL()
      {
          return _url;
      }
  
      public String getURL(String anchor, boolean includeParameters)
      {
          if (anchor == null)
          	return _url;
          	
          	return _url + "#" + anchor;
      }
  
      public String getAbsoluteURL()
      {
          return _url;
      }
  
      public String getAbsoluteURL(
          String scheme,
          String server,
          int port,
          String anchor,
          boolean includeParameters)
      {
          return getURL(anchor, false);
      }
  
      public String[] getParameterNames()
      {
          return null;
      }
  
      public String[] getParameterValues(String name)
      {
          throw new IllegalArgumentException();
      }
  
  }
  
  
  
  1.7       +24 -1     jakarta-tapestry/doc/src/ComponentReference/GenericLink.html
  
  Index: GenericLink.html
  ===================================================================
  RCS file: /home/cvs/jakarta-tapestry/doc/src/ComponentReference/GenericLink.html,v
  retrieving revision 1.6
  retrieving revision 1.7
  diff -u -r1.6 -r1.7
  --- GenericLink.html	4 Sep 2002 22:48:32 -0000	1.6
  +++ GenericLink.html	27 Jan 2003 16:30:13 -0000	1.7
  @@ -109,6 +109,29 @@
   		<td>Controls whether the link is produced. If disabled, the portion of the 
       template the link surrounds is still rendered, but not the link itself.</td>
   	</tr>
  +	
  +  <tr>
  +    <td>anchor</td>
  +    <td>String</td>
  +    <td>in</td>
  +   	<td>no</td>
  +		<td>&nbsp;</td>
  +		<td>
  +    The name of an anchor or element to link to. The final URL will have '#' 
  +    and the anchor appended to it.
  +    </td>
  +	</tr>
  +	
  +	<tr>
  +		<td>renderer</td>
  +		<td><a href="../api/net/sf/tapestry/link/ILinkRenderer.html">ILinkRenderer</a></td>
  +		<td>in</td>
  +		<td>no</td>
  +		<td>&nbsp;</td>
  +		<td>
  +		The object which will actually render the link.
  +			</td>
  +	</tr>	
   	</table>
               <P>Body: <STRONG>rendered</STRONG><BR>Informal parameters: 
               <STRONG>allowed</STRONG>
  
  
  
  1.7       +14 -28    jakarta-tapestry/doc/src/ComponentReference/ActionLink.html
  
  Index: ActionLink.html
  ===================================================================
  RCS file: /home/cvs/jakarta-tapestry/doc/src/ComponentReference/ActionLink.html,v
  retrieving revision 1.6
  retrieving revision 1.7
  diff -u -r1.6 -r1.7
  --- ActionLink.html	18 Sep 2002 22:07:40 -0000	1.6
  +++ ActionLink.html	27 Jan 2003 16:30:13 -0000	1.7
  @@ -123,33 +123,8 @@
       itself.
       </td>
   	</tr>
  -  <tr>
  -    <td>scheme</td>
  -    <td>String</td>
  -    <td>in</td>
  -   	<td>no</td>
  -		<td>&nbsp;</td>
  -		<td>
  -    If specified, then a longer URL (including scheme, server and possibly port) 
  -    is generated using the specified scheme. Server is determined fromt he 
  -    incoming request, and port is deterimined from the port paramter or the 
  -    incoming request.     
  -    </td>
  -	</tr>
  -  <tr>
  -    <td>port</td>
  -    <td>int</td>
  -    <td>in</td>
  -   	<td>no</td>
  -		<td>&nbsp;</td>
  -		<td>
  -    If specified, then a longer URL (including scheme, server and port) is 
  -    generated using the specified port. The server is determined from the 
  -    incoming request, the scheme from the scheme paramter or the incoming 
  -    request. 
  -    </td>
  -	</tr>
  -  <tr>
  +	
  +	  <tr>
       <td>anchor</td>
       <td>String</td>
       <td>in</td>
  @@ -160,6 +135,17 @@
       and the anchor appended to it.
       </td>
   	</tr>
  +		
  +	<tr>
  +		<td>renderer</td>
  +		<td><a href="../api/net/sf/tapestry/link/ILinkRenderer.html">ILinkRenderer</a></td>
  +		<td>in</td>
  +		<td>no</td>
  +		<td>&nbsp;</td>
  +		<td>
  +		The object which will actually render the link.
  +			</td>
  +	</tr>		
   	</table>
     <P>
     Body: <STRONG>rendered</STRONG><BR>
  
  
  
  1.6       +13 -28    jakarta-tapestry/doc/src/ComponentReference/PageLink.html
  
  Index: PageLink.html
  ===================================================================
  RCS file: /home/cvs/jakarta-tapestry/doc/src/ComponentReference/PageLink.html,v
  retrieving revision 1.5
  retrieving revision 1.6
  diff -u -r1.5 -r1.6
  --- PageLink.html	27 Nov 2002 10:28:11 -0000	1.5
  +++ PageLink.html	27 Jan 2003 16:30:13 -0000	1.6
  @@ -122,32 +122,6 @@
       </td>
   	</tr>
     <tr>
  -    <td>scheme</td>
  -    <td>String</td>
  -    <td>in</td>
  -   	<td>no</td>
  -		<td>&nbsp;</td>
  -		<td>
  -    If specified, then a longer URL (including scheme, server and possibly port) 
  -    is generated using the specified scheme. Server is determined fromt he 
  -    incoming request, and port is deterimined from the port paramter or the 
  -    incoming request. 
  -    </td>
  -	</tr>
  -  <tr>
  -    <td>port</td>
  -    <td>int</td>
  -    <td>in</td>
  -   	<td>no</td>
  -		<td>&nbsp;</td>
  -		<td>
  -    If specified, then a longer URL (including scheme, server and port) is 
  -    generated using the specified port. The server is determined from the 
  -    incoming request, the scheme from the scheme paramter or the incoming 
  -    request.     
  -    </td>
  -	</tr>
  -  <tr>
       <td>anchor</td>
       <td>String</td>
       <td>in</td>
  @@ -155,9 +129,20 @@
   		<td>&nbsp;</td>
   		<td>
       The name of an anchor or element to link to. The final URL will have '#' 
  -    and the anchor appended to it. 
  +    and the anchor appended to it.
       </td>
   	</tr>
  +	
  +	<tr>
  +		<td>renderer</td>
  +		<td><a href="../api/net/sf/tapestry/link/ILinkRenderer.html">ILinkRenderer</a></td>
  +		<td>in</td>
  +		<td>no</td>
  +		<td>&nbsp;</td>
  +		<td>
  +		The object which will actually render the link.
  +			</td>
  +	</tr>	
   	</table><BR>
     Body: <STRONG>rendered</STRONG><BR>
     Informal parameters: <STRONG>allowed</STRONG><br>
  
  
  
  1.3       +13 -18    jakarta-tapestry/doc/src/ComponentReference/ExternalLink.html
  
  Index: ExternalLink.html
  ===================================================================
  RCS file: /home/cvs/jakarta-tapestry/doc/src/ComponentReference/ExternalLink.html,v
  retrieving revision 1.2
  retrieving revision 1.3
  diff -u -r1.2 -r1.3
  --- ExternalLink.html	15 Sep 2002 22:01:47 -0000	1.2
  +++ ExternalLink.html	27 Jan 2003 16:30:13 -0000	1.3
  @@ -118,32 +118,27 @@
       template the link surrounds is still rendered, but not the link itself.
       </td>
   	</tr>
  -  <tr>
  -    <td>scheme</td>
  +	  <tr>
  +    <td>anchor</td>
       <td>String</td>
       <td>in</td>
      	<td>no</td>
   		<td>&nbsp;</td>
   		<td>
  -    If specified, then a longer URL (including scheme, server and possibly port) 
  -    is generated using the specified scheme. Server is determined fromt he 
  -    incoming request, and port is deterimined from the port paramter or the 
  -    incoming request.     
  +    The name of an anchor or element to link to. The final URL will have '#' 
  +    and the anchor appended to it.
       </td>
   	</tr>
  -  <tr>
  -    <td>port</td>
  -    <td>int</td>
  -    <td>in</td>
  -   	<td>no</td>
  +	<tr>
  +		<td>renderer</td>
  +		<td><a href="../api/net/sf/tapestry/link/ILinkRenderer.html">ILinkRenderer</a></td>
  +		<td>in</td>
  +		<td>no</td>
   		<td>&nbsp;</td>
   		<td>
  -    If specified, then a longer URL (including scheme, server and port) is 
  -    generated using the specified port. The server is determined from the 
  -    incoming request, the scheme from the scheme parameter or the incoming 
  -    request. 
  -    </td>
  -	</tr>
  +		The object which will actually render the link.
  +			</td>
  +	</tr>	
   	</table>
     <P>Body: <STRONG>rendered</STRONG><BR>
     Informal parameters:<STRONG>allowed</STRONG>
  
  
  
  1.5       +14 -28    jakarta-tapestry/doc/src/ComponentReference/ServiceLink.html
  
  Index: ServiceLink.html
  ===================================================================
  RCS file: /home/cvs/jakarta-tapestry/doc/src/ComponentReference/ServiceLink.html,v
  retrieving revision 1.4
  retrieving revision 1.5
  diff -u -r1.4 -r1.5
  --- ServiceLink.html	26 Nov 2002 11:48:26 -0000	1.4
  +++ ServiceLink.html	27 Jan 2003 16:30:13 -0000	1.5
  @@ -137,32 +137,7 @@
       removed in a later release entirely. 
       </td>
   	</tr>
  -  <tr>
  -    <td>scheme</td>
  -    <td>String</td>
  -    <td>in</td>
  -   	<td>no</td>
  -		<td>&nbsp;</td>
  -		<td>
  -    If specified, then a longer URL (including scheme, server and possibly port) 
  -    is generated using the specified scheme. Server is determined fromt he 
  -    incoming request, and port is deterimined from the port paramter or the 
  -    incoming request. 
  -    </td>
  -	</tr>
  -  <tr>
  -    <td>port</td>
  -    <td>int</td>
  -    <td>in</td>
  -   	<td>no</td>
  -		<td>&nbsp;</td>
  -		<td>
  -    If specified, then a longer URL (including scheme, server and port) is 
  -    generated using the specified port. The server is determined from the 
  -    incoming request, the scheme from the scheme paramter or the incoming 
  -    request.     
  -    </td>
  -	</tr>
  +
     <tr>
       <td>anchor</td>
       <td>String</td>
  @@ -171,9 +146,20 @@
   		<td>&nbsp;</td>
   		<td>
       The name of an anchor or element to link to. The final URL will have '#' 
  -    and the anchor appended to it. 
  +    and the anchor appended to it.
       </td>
   	</tr>
  +	
  +	<tr>
  +		<td>renderer</td>
  +		<td><a href="../api/net/sf/tapestry/link/ILinkRenderer.html">ILinkRenderer</a></td>
  +		<td>in</td>
  +		<td>no</td>
  +		<td>&nbsp;</td>
  +		<td>
  +		The object which will actually render the link.
  +			</td>
  +	</tr>	
   	</table><BR>Body: 
               <STRONG>rendered</STRONG><BR>Informal parameters: 
               <STRONG>allowed</STRONG>
  
  
  
  1.7       +12 -27    jakarta-tapestry/doc/src/ComponentReference/DirectLink.html
  
  Index: DirectLink.html
  ===================================================================
  RCS file: /home/cvs/jakarta-tapestry/doc/src/ComponentReference/DirectLink.html,v
  retrieving revision 1.6
  retrieving revision 1.7
  diff -u -r1.6 -r1.7
  --- DirectLink.html	24 Nov 2002 21:26:39 -0000	1.6
  +++ DirectLink.html	27 Jan 2003 16:30:13 -0000	1.7
  @@ -155,32 +155,7 @@
       itself.
       </td>
   	</tr>
  -  <tr>
  -    <td>scheme</td>
  -    <td>String</td>
  -    <td>in</td>
  -   	<td>no</td>
  -		<td>&nbsp;</td>
  -		<td>
  -    If specified, then a longer URL (including scheme, server and possibly port) 
  -    is generated using the specified scheme. Server is determined fromt he 
  -    incoming request, and port is deterimined from the port paramter or the 
  -    incoming request.     
  -    </td>
  -	</tr>
  -  <tr>
  -    <td>port</td>
  -    <td>int</td>
  -    <td>in</td>
  -   	<td>no</td>
  -		<td>&nbsp;</td>
  -		<td>
  -    If specified, then a longer URL (including scheme, server and port) is 
  -    generated using the specified port. The server is determined from the 
  -    incoming request, the scheme from the scheme parameter or the incoming 
  -    request. 
  -    </td>
  -	</tr>
  +
     <tr>
       <td>anchor</td>
       <td>String</td>
  @@ -192,6 +167,16 @@
       and the anchor appended to it.
       </td>
   	</tr>
  +	<tr>
  +		<td>renderer</td>
  +		<td><a href="../api/net/sf/tapestry/link/ILinkRenderer.html">ILinkRenderer</a></td>
  +		<td>in</td>
  +		<td>no</td>
  +		<td>&nbsp;</td>
  +		<td>
  +		The object which will actually render the link.
  +			</td>
  +	</tr>	
   	</table>
               <P>Body: <STRONG>rendered</STRONG><BR>Informal parameters: 
               <STRONG>allowed</STRONG>
  
  
  
  1.10      +14 -4     jakarta-tapestry/junit/src/net/sf/tapestry/junit/TapestryTestCase.java
  
  Index: TapestryTestCase.java
  ===================================================================
  RCS file: /home/cvs/jakarta-tapestry/junit/src/net/sf/tapestry/junit/TapestryTestCase.java,v
  retrieving revision 1.9
  retrieving revision 1.10
  diff -u -r1.9 -r1.10
  --- TapestryTestCase.java	17 Jan 2003 17:41:27 -0000	1.9
  +++ TapestryTestCase.java	27 Jan 2003 16:30:13 -0000	1.10
  @@ -54,6 +54,8 @@
    */
   package net.sf.tapestry.junit;
   
  +import java.util.ArrayList;
  +import java.util.Arrays;
   import java.util.List;
   import java.util.Locale;
   
  @@ -85,7 +87,8 @@
   
   public class TapestryTestCase extends TestCase
   {
  -    protected static final boolean IS_JDK13 = System.getProperty("java.specification.version").equals("1.3");
  +    protected static final boolean IS_JDK13 =
  +        System.getProperty("java.specification.version").equals("1.3");
   
       private IResourceResolver _resolver = new DefaultResourceResolver();
   
  @@ -144,7 +147,8 @@
       {
           String adjustedClassName = "/" + getClass().getName().replace('.', '/') + ".class";
   
  -        IResourceLocation classResourceLocation = new ClasspathResourceLocation(_resolver, adjustedClassName);
  +        IResourceLocation classResourceLocation =
  +            new ClasspathResourceLocation(_resolver, adjustedClassName);
   
           IResourceLocation appSpecLocation = classResourceLocation.getRelativeLocation(simpleName);
           return appSpecLocation;
  @@ -159,6 +163,11 @@
           return parser.parseLibrarySpecification(location, _resolver);
       }
   
  +    protected void checkList(String propertyName, String[] expected, String[] actual)
  +    {
  +        checkList(propertyName, expected, Arrays.asList(actual));
  +    }
  +
       protected void checkList(String propertyName, String[] expected, List actual)
       {
           int count = Tapestry.size(actual);
  @@ -181,7 +190,8 @@
           if (ex.getMessage().indexOf(string) >= 0)
               return;
   
  -        throw new AssertionFailedError("Exception " + ex + " does not contain sub-string '" + string + "'.");
  +        throw new AssertionFailedError(
  +            "Exception " + ex + " does not contain sub-string '" + string + "'.");
       }
   
       protected void unreachable()
  
  
  
  1.21      +3 -1      jakarta-tapestry/junit/src/net/sf/tapestry/junit/TapestrySuite.java
  
  Index: TapestrySuite.java
  ===================================================================
  RCS file: /home/cvs/jakarta-tapestry/junit/src/net/sf/tapestry/junit/TapestrySuite.java,v
  retrieving revision 1.20
  retrieving revision 1.21
  diff -u -r1.20 -r1.21
  --- TapestrySuite.java	24 Jan 2003 00:49:38 -0000	1.20
  +++ TapestrySuite.java	27 Jan 2003 16:30:13 -0000	1.21
  @@ -87,6 +87,8 @@
       {
           TestSuite suite = new TestSuite();
   
  +		suite.addTestSuite(TestStaticLink.class);
  +		suite.addTestSuite(TestEngineServiceLink.class);
           suite.addTestSuite(TestAdaptorRegistry.class);
           suite.addTestSuite(TestTapestryCoerceToIterator.class);
           suite.addTestSuite(TestPool.class);
  
  
  
  1.12      +8 -2      jakarta-tapestry/junit/src/net/sf/tapestry/junit/MockEngine.java
  
  Index: MockEngine.java
  ===================================================================
  RCS file: /home/cvs/jakarta-tapestry/junit/src/net/sf/tapestry/junit/MockEngine.java,v
  retrieving revision 1.11
  retrieving revision 1.12
  diff -u -r1.11 -r1.12
  --- MockEngine.java	24 Jan 2003 00:49:38 -0000	1.11
  +++ MockEngine.java	27 Jan 2003 16:30:14 -0000	1.12
  @@ -91,6 +91,7 @@
   
       private boolean _refreshing;
       private Pool _pool = new Pool();
  +    private String _servletPath;
   
       public void forgetPage(String name)
       {
  @@ -127,7 +128,7 @@
   
       public String getServletPath()
       {
  -        return null;
  +        return _servletPath;
       }
   
       public String getContextPath()
  @@ -232,6 +233,11 @@
       public IComponentClassEnhancer getComponentClassEnhancer()
       {
           return null;
  +    }
  +
  +    public void setServletPath(String servletPath)
  +    {
  +        _servletPath = servletPath;
       }
   
   }
  
  
  
  1.1                  jakarta-tapestry/junit/src/net/sf/tapestry/junit/TestEngineServiceLink.java
  
  Index: TestEngineServiceLink.java
  ===================================================================
  /*
   *  ====================================================================
   *  The Apache Software License, Version 1.1
   *
   *  Copyright (c) 2002 The Apache Software Foundation.  All rights
   *  reserved.
   *
   *  Redistribution and use in source and binary forms, with or without
   *  modification, are permitted provided that the following conditions
   *  are met:
   *
   *  1. Redistributions of source code must retain the above copyright
   *  notice, this list of conditions and the following disclaimer.
   *
   *  2. Redistributions in binary form must reproduce the above copyright
   *  notice, this list of conditions and the following disclaimer in
   *  the documentation and/or other materials provided with the
   *  distribution.
   *
   *  3. The end-user documentation included with the redistribution,
   *  if any, must include the following acknowledgment:
   *  "This product includes software developed by the
   *  Apache Software Foundation (http://www.apache.org/)."
   *  Alternately, this acknowledgment may appear in the software itself,
   *  if and wherever such third-party acknowledgments normally appear.
   *
   *  4. The names "Apache" and "Apache Software Foundation" and
   *  "Apache Tapestry" must not be used to endorse or promote products
   *  derived from this software without prior written permission. For
   *  written permission, please contact apache@apache.org.
   *
   *  5. Products derived from this software may not be called "Apache",
   *  "Apache Tapestry", nor may "Apache" appear in their name, without
   *  prior written permission of the Apache Software Foundation.
   *
   *  THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   *  WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   *  OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   *  DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   *  ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   *  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   *  USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   *  ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   *  OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   *  OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   *  SUCH DAMAGE.
   *  ====================================================================
   *
   *  This software consists of voluntary contributions made by many
   *  individuals on behalf of the Apache Software Foundation.  For more
   *  information on the Apache Software Foundation, please see
   *  <http://www.apache.org/>.
   */
  package net.sf.tapestry.junit;
  
  import java.io.BufferedReader;
  import java.io.IOException;
  import java.io.UnsupportedEncodingException;
  import java.security.Principal;
  import java.util.Enumeration;
  import java.util.Locale;
  import java.util.Map;
  
  import javax.servlet.RequestDispatcher;
  import javax.servlet.ServletInputStream;
  import javax.servlet.http.Cookie;
  import javax.servlet.http.HttpServletRequest;
  import javax.servlet.http.HttpServletResponse;
  import javax.servlet.http.HttpSession;
  
  import net.sf.tapestry.ApplicationServlet;
  import net.sf.tapestry.RequestContext;
  import net.sf.tapestry.Tapestry;
  import net.sf.tapestry.engine.EngineServiceLink;
  import net.sf.tapestry.junit.mock.MockContext;
  import net.sf.tapestry.junit.mock.MockServletConfig;
  
  public class TestEngineServiceLink extends TapestryTestCase
  {
      private class TestRequest implements HttpServletRequest
      {
          public String getAuthType()
          {
              return null;
          }
  
          public String getContextPath()
          {
              return null;
          }
  
          public Cookie[] getCookies()
          {
              return null;
          }
  
          public long getDateHeader(String arg0)
          {
              return 0;
          }
  
          public String getHeader(String arg0)
          {
              return null;
          }
  
          public Enumeration getHeaderNames()
          {
              return null;
          }
  
          public Enumeration getHeaders(String arg0)
          {
              return null;
          }
  
          public int getIntHeader(String arg0)
          {
              return 0;
          }
  
          public String getMethod()
          {
              return null;
          }
  
          public String getPathInfo()
          {
              return null;
          }
  
          public String getPathTranslated()
          {
              return null;
          }
  
          public String getQueryString()
          {
              return null;
          }
  
          public String getRemoteUser()
          {
              return null;
          }
  
          public String getRequestedSessionId()
          {
              return null;
          }
  
          public String getRequestURI()
          {
              return null;
          }
  
          public StringBuffer getRequestURL()
          {
              return null;
          }
  
          public String getServletPath()
          {
              return null;
          }
  
          public HttpSession getSession()
          {
              return null;
          }
  
          public HttpSession getSession(boolean arg0)
          {
              return null;
          }
  
          public Principal getUserPrincipal()
          {
              return null;
          }
  
          public boolean isRequestedSessionIdFromCookie()
          {
              return false;
          }
  
          public boolean isRequestedSessionIdFromUrl()
          {
              return false;
          }
  
          public boolean isRequestedSessionIdFromURL()
          {
              return false;
          }
  
          public boolean isRequestedSessionIdValid()
          {
              return false;
          }
  
          public boolean isUserInRole(String arg0)
          {
              return false;
          }
  
          public Object getAttribute(String arg0)
          {
              return null;
          }
  
          public Enumeration getAttributeNames()
          {
              return null;
          }
  
          public String getCharacterEncoding()
          {
              return null;
          }
  
          public int getContentLength()
          {
              return 0;
          }
  
          public String getContentType()
          {
              return null;
          }
  
          public ServletInputStream getInputStream() throws IOException
          {
              return null;
          }
  
          public Locale getLocale()
          {
              return null;
          }
  
          public Enumeration getLocales()
          {
              return null;
          }
  
          public String getParameter(String arg0)
          {
              return null;
          }
  
          public Map getParameterMap()
          {
              return null;
          }
  
          public Enumeration getParameterNames()
          {
              return null;
          }
  
          public String[] getParameterValues(String arg0)
          {
              return null;
          }
  
          public String getProtocol()
          {
              return null;
          }
  
          public BufferedReader getReader() throws IOException
          {
              return null;
          }
  
          public String getRealPath(String arg0)
          {
              return null;
          }
  
          public String getRemoteAddr()
          {
              return null;
          }
  
          public String getRemoteHost()
          {
              return null;
          }
  
          public RequestDispatcher getRequestDispatcher(String arg0)
          {
              return null;
          }
  
          public String getScheme()
          {
              return "http";
          }
  
          public String getServerName()
          {
              return "testserver";
          }
  
          public int getServerPort()
          {
              return 80;
          }
  
          public boolean isSecure()
          {
              return false;
          }
  
          public void removeAttribute(String arg0)
          {
          }
  
          public void setAttribute(String arg0, Object arg1)
          {
          }
  
          public void setCharacterEncoding(String arg0) throws UnsupportedEncodingException
          {
          }
  
      }
  
      public TestEngineServiceLink(String name)
      {
          super(name);
      }
  
      private MockRequestCycle create(String servletPath) throws Exception
      {
          MockContext servletContext = new MockContext();
          MockServletConfig config = new MockServletConfig("servlet", servletContext);
          ApplicationServlet servlet = new ApplicationServlet();
  
          servlet.init(config);
  
          MockEngine engine = new MockEngine();
          engine.setServletPath(servletPath);
  
          HttpServletRequest request = new TestRequest();
          RequestContext context = new RequestContext(servlet, request, null);
  
          return new MockRequestCycle(engine, context);
      }
  
      public void testGetURL() throws Exception
      {
          MockRequestCycle c = create("/context/servlet");
  
          EngineServiceLink l = new EngineServiceLink(c, "myservice", null, null, true);
  
          assertEquals("/context/servlet?service=myservice", l.getURL());
  
          assertEquals("/context/servlet?service=myservice", c.getLastEncodedURL());
  
          assertEquals("/context/servlet", l.getURL(null, false));
  
          assertEquals("/context/servlet#anchor", l.getURL("anchor", false));
  
          assertEquals("/context/servlet?service=myservice#anchor", l.getURL("anchor", true));
  
          checkList(
              "parameterNames",
              new String[] { Tapestry.SERVICE_QUERY_PARAMETER_NAME },
              l.getParameterNames());
      }
  
      public void testGetAbsoluteURL() throws Exception
      {
          MockRequestCycle c = create("/context/servlet");
  
          EngineServiceLink l = new EngineServiceLink(c, "myservice", null, null, true);
  
          assertEquals("http://testserver/context/servlet?service=myservice", l.getAbsoluteURL());
  
          assertEquals("http://testserver/context/servlet?service=myservice", c.getLastEncodedURL());
  
          assertEquals(
              "http://testserver/context/servlet#anchor",
              l.getAbsoluteURL(null, null, 0, "anchor", false));
  
          assertEquals(
              "http://testserver/context/servlet?service=myservice#anchor",
              l.getAbsoluteURL(null, null, 0, "anchor", true));
  
          assertEquals(
              "frob://magic:77/context/servlet?service=myservice",
              l.getAbsoluteURL("frob", "magic", 77, null, true));
      }
  
      public void testContext() throws Exception
      {
          MockRequestCycle c = create("/alpha/bravo");
  
          EngineServiceLink l =
              new EngineServiceLink(
                  c,
                  "myservice",
                  new String[] { "Alpha", "Bravo", "Tango" },
                  null,
                  true);
  
          checkList(
              "parameterNames",
              new String[] {
                  Tapestry.SERVICE_QUERY_PARAMETER_NAME,
                  Tapestry.CONTEXT_QUERY_PARMETER_NAME },
              l.getParameterNames());
  
          checkList(
              "service parameters values",
              new String[] { "myservice" },
              l.getParameterValues(Tapestry.SERVICE_QUERY_PARAMETER_NAME));
  
          checkList(
              "context parameter values",
              new String[] { "Alpha/Bravo/Tango" },
              l.getParameterValues(Tapestry.CONTEXT_QUERY_PARMETER_NAME));
  
          assertEquals("/alpha/bravo?service=myservice&context=Alpha/Bravo/Tango", l.getURL());
  
      }
  
      public void testServiceParameters() throws Exception
      {
          MockRequestCycle c = create("/alpha/bravo");
  
          EngineServiceLink l =
              new EngineServiceLink(
                  c,
                  "myservice",
                  null,
                  new String[] { "One Two", "Three Four" },
                  true);
  
  		assertEquals("/alpha/bravo?service=myservice&sp=One+Two&sp=Three+Four", l.getURL());
  
          checkList(
              "parameterNames",
              new String[] {
                  Tapestry.SERVICE_QUERY_PARAMETER_NAME,
                  Tapestry.PARAMETERS_QUERY_PARAMETER_NAME },
              l.getParameterNames());
  
          checkList(
              "service parameters values",
              new String[] { "One Two", "Three Four" },
              l.getParameterValues(Tapestry.PARAMETERS_QUERY_PARAMETER_NAME));
      }
  
      public void testUnknownParameter() throws Exception
      {
          MockRequestCycle c = create("/context/servlet");
  
          EngineServiceLink l = new EngineServiceLink(c, "myservice", null, null, true);
  
          try
          {
              l.getParameterValues("unknown");
  
              unreachable();
          }
          catch (IllegalArgumentException ex)
          {
          }
      }
  
  }
  
  
  
  1.1                  jakarta-tapestry/junit/src/net/sf/tapestry/junit/TestStaticLink.java
  
  Index: TestStaticLink.java
  ===================================================================
  /*
   *  ====================================================================
   *  The Apache Software License, Version 1.1
   *
   *  Copyright (c) 2002 The Apache Software Foundation.  All rights
   *  reserved.
   *
   *  Redistribution and use in source and binary forms, with or without
   *  modification, are permitted provided that the following conditions
   *  are met:
   *
   *  1. Redistributions of source code must retain the above copyright
   *  notice, this list of conditions and the following disclaimer.
   *
   *  2. Redistributions in binary form must reproduce the above copyright
   *  notice, this list of conditions and the following disclaimer in
   *  the documentation and/or other materials provided with the
   *  distribution.
   *
   *  3. The end-user documentation included with the redistribution,
   *  if any, must include the following acknowledgment:
   *  "This product includes software developed by the
   *  Apache Software Foundation (http://www.apache.org/)."
   *  Alternately, this acknowledgment may appear in the software itself,
   *  if and wherever such third-party acknowledgments normally appear.
   *
   *  4. The names "Apache" and "Apache Software Foundation" and
   *  "Apache Tapestry" must not be used to endorse or promote products
   *  derived from this software without prior written permission. For
   *  written permission, please contact apache@apache.org.
   *
   *  5. Products derived from this software may not be called "Apache",
   *  "Apache Tapestry", nor may "Apache" appear in their name, without
   *  prior written permission of the Apache Software Foundation.
   *
   *  THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   *  WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   *  OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   *  DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   *  ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   *  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   *  USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   *  ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   *  OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   *  OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   *  SUCH DAMAGE.
   *  ====================================================================
   *
   *  This software consists of voluntary contributions made by many
   *  individuals on behalf of the Apache Software Foundation.  For more
   *  information on the Apache Software Foundation, please see
   *  <http://www.apache.org/>.
   */
  package net.sf.tapestry.junit;
  
  import net.sf.tapestry.engine.ILink;
  import net.sf.tapestry.link.StaticLink;
  
  /**
   *  Tests for {@link net.sf.tapestry.link.StaticLink}.
   *
   *  @author Howard Lewis Ship
   *  @version $Id: TestStaticLink.java,v 1.1 2003/01/27 16:30:14 hlship Exp $
   *  @since 2.4
   * 
   **/
  
  public class TestStaticLink extends TapestryTestCase
  {
  	private static final String URL = "http://host/path";
  	
  		ILink l = new StaticLink(URL);
  		
  
      public TestStaticLink(String name)
      {
          super(name);
      }
  
  	public void testURL()
  	{
  		assertEquals(URL, l.getURL());
  	}
  	
  	public void testAbsoluteURL()
  	{
  		assertEquals(URL, l.getAbsoluteURL());
  	}
  
  	public void testURLWithAnchor()
  	{
  		assertEquals(URL, l.getURL(null, false));
  		assertEquals(URL + "#anchor", l.getURL("anchor", false));
  		assertEquals(URL + "#feeble", l.getURL("feeble", true));
  	}
  	
  	public void testAbsoluteURLWithParameters()
  	{
  		assertEquals(URL + "#anchor", l.getAbsoluteURL("scheme", "server", 8080, "anchor", false));
  	}
  	
  	public void testGetParameterNames()
  	{
  		assertEquals(null, l.getParameterNames());
  	}
  	
  	public void testGetParameterValues()
  	{
  		try
  		{
  			l.getParameterValues("any");
  			
  			unreachable();
  		}
  		catch (IllegalArgumentException ex)
  		{
  		}
  	}
  }
  
  
  
  1.1                  jakarta-tapestry/junit/src/net/sf/tapestry/junit/MockRequestCycle.java
  
  Index: MockRequestCycle.java
  ===================================================================
  /*
   *  ====================================================================
   *  The Apache Software License, Version 1.1
   *
   *  Copyright (c) 2002 The Apache Software Foundation.  All rights
   *  reserved.
   *
   *  Redistribution and use in source and binary forms, with or without
   *  modification, are permitted provided that the following conditions
   *  are met:
   *
   *  1. Redistributions of source code must retain the above copyright
   *  notice, this list of conditions and the following disclaimer.
   *
   *  2. Redistributions in binary form must reproduce the above copyright
   *  notice, this list of conditions and the following disclaimer in
   *  the documentation and/or other materials provided with the
   *  distribution.
   *
   *  3. The end-user documentation included with the redistribution,
   *  if any, must include the following acknowledgment:
   *  "This product includes software developed by the
   *  Apache Software Foundation (http://www.apache.org/)."
   *  Alternately, this acknowledgment may appear in the software itself,
   *  if and wherever such third-party acknowledgments normally appear.
   *
   *  4. The names "Apache" and "Apache Software Foundation" and
   *  "Apache Tapestry" must not be used to endorse or promote products
   *  derived from this software without prior written permission. For
   *  written permission, please contact apache@apache.org.
   *
   *  5. Products derived from this software may not be called "Apache",
   *  "Apache Tapestry", nor may "Apache" appear in their name, without
   *  prior written permission of the Apache Software Foundation.
   *
   *  THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   *  WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   *  OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   *  DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   *  ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   *  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   *  USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   *  ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   *  OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   *  OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   *  SUCH DAMAGE.
   *  ====================================================================
   *
   *  This software consists of voluntary contributions made by many
   *  individuals on behalf of the Apache Software Foundation.  For more
   *  information on the Apache Software Foundation, please see
   *  <http://www.apache.org/>.
   */
  package net.sf.tapestry.junit;
  
  import net.sf.tapestry.IComponent;
  import net.sf.tapestry.IEngine;
  import net.sf.tapestry.IEngineService;
  import net.sf.tapestry.IForm;
  import net.sf.tapestry.IMarkupWriter;
  import net.sf.tapestry.IMonitor;
  import net.sf.tapestry.IPage;
  import net.sf.tapestry.IRequestCycle;
  import net.sf.tapestry.PageRecorderCommitException;
  import net.sf.tapestry.RequestContext;
  import net.sf.tapestry.RequestCycleException;
  import net.sf.tapestry.StaleLinkException;
  
  /**
   *  Used to simulate an {@link net.sf.tapestry.IRequestCycle} in some tests.
   * 
   *
   *  @author Howard Lewis Ship
   *  @version $Id: MockRequestCycle.java,v 1.1 2003/01/27 16:30:14 hlship Exp $
   *  @since 2.4
   **/
  public class MockRequestCycle implements IRequestCycle
  {
      private IEngine _engine;
      private String _lastEncodedURL;
      private RequestContext _context;
  
      public MockRequestCycle(IEngine engine, RequestContext context)
      {
          _engine = engine;
          _context = context;
      }
  
      public void cleanup()
      {
      }
  
      public String encodeURL(String URL)
      {
          _lastEncodedURL = URL;
          
          return URL;
      }
  
      public IEngine getEngine()
      {
          return _engine;
      }
  
      public Object getAttribute(String name)
      {
          return null;
      }
  
      public IMonitor getMonitor()
      {
          return null;
      }
  
      public String getNextActionId()
      {
          return null;
      }
  
      public IPage getPage()
      {
          return null;
      }
  
      public IPage getPage(String name)
      {
          return null;
      }
  
      public RequestContext getRequestContext()
      {
          return _context;
      }
  
      public boolean isRewinding()
      {
          return false;
      }
  
      public boolean isRewound(IComponent component) throws StaleLinkException
      {
          return false;
      }
  
      public void removeAttribute(String name)
      {
      }
  
      public void renderPage(IMarkupWriter writer) throws RequestCycleException
      {
      }
  
      public void rewindPage(String targetActionId, IComponent targetComponent)
          throws RequestCycleException
      {
      }
  
      public void setAttribute(String name, Object value)
      {
      }
  
      public void setPage(IPage page)
      {
      }
  
      public void setPage(String name)
      {
      }
  
      public void commitPageChanges() throws PageRecorderCommitException
      {
      }
  
      public IEngineService getService()
      {
          return null;
      }
  
      public void rewindForm(IForm form, String targetActionId) throws RequestCycleException
      {
      }
  
      public void discardPage(String name)
      {
      }
  
      public void setServiceParameters(Object[] parameters)
      {
      }
  
      public Object[] getServiceParameters()
      {
          return null;
      }
  
      public String getLastEncodedURL()
      {
          return _lastEncodedURL;
      }
  
  }
  
  
  
  1.9       +3 -4      jakarta-tapestry/framework/src/net/sf/tapestry/engine/RestartService.java
  
  Index: RestartService.java
  ===================================================================
  RCS file: /home/cvs/jakarta-tapestry/framework/src/net/sf/tapestry/engine/RestartService.java,v
  retrieving revision 1.8
  retrieving revision 1.9
  diff -u -r1.8 -r1.9
  --- RestartService.java	24 Jan 2003 00:49:33 -0000	1.8
  +++ RestartService.java	27 Jan 2003 16:30:17 -0000	1.9
  @@ -58,7 +58,6 @@
   
   import javax.servlet.ServletException;
   
  -import net.sf.tapestry.Gesture;
   import net.sf.tapestry.IComponent;
   import net.sf.tapestry.IEngineServiceView;
   import net.sf.tapestry.IRequestCycle;
  @@ -80,13 +79,13 @@
   public class RestartService extends AbstractService
   {
   
  -    public Gesture buildGesture(IRequestCycle cycle, IComponent component, Object[] parameters)
  +    public ILink getLink(IRequestCycle cycle, IComponent component, Object[] parameters)
       {
           if (Tapestry.size(parameters) != 0)
               throw new IllegalArgumentException(
                   Tapestry.getString("service-no-parameters", Tapestry.RESTART_SERVICE));
   
  -        return assembleGesture(cycle, Tapestry.RESTART_SERVICE, null, null, true);
  +        return constructLink(cycle, Tapestry.RESTART_SERVICE, null, null, true);
       }
   
       public boolean service(
  
  
  
  1.9       +3 -4      jakarta-tapestry/framework/src/net/sf/tapestry/engine/PageService.java
  
  Index: PageService.java
  ===================================================================
  RCS file: /home/cvs/jakarta-tapestry/framework/src/net/sf/tapestry/engine/PageService.java,v
  retrieving revision 1.8
  retrieving revision 1.9
  diff -u -r1.8 -r1.9
  --- PageService.java	24 Jan 2003 00:49:33 -0000	1.8
  +++ PageService.java	27 Jan 2003 16:30:17 -0000	1.9
  @@ -59,7 +59,6 @@
   import javax.servlet.ServletException;
   
   import net.sf.tapestry.ApplicationRuntimeException;
  -import net.sf.tapestry.Gesture;
   import net.sf.tapestry.IComponent;
   import net.sf.tapestry.IEngineServiceView;
   import net.sf.tapestry.IPage;
  @@ -81,13 +80,13 @@
   public class PageService extends AbstractService
   {
   
  -    public Gesture buildGesture(IRequestCycle cycle, IComponent component, Object[] parameters)
  +    public ILink getLink(IRequestCycle cycle, IComponent component, Object[] parameters)
       {
           if (Tapestry.size(parameters) != 1)
               throw new IllegalArgumentException(
                   Tapestry.getString("service-single-parameter", Tapestry.PAGE_SERVICE));
   
  -        return assembleGesture(cycle, Tapestry.PAGE_SERVICE, (String[]) parameters, null, true);
  +        return constructLink(cycle, Tapestry.PAGE_SERVICE, (String[]) parameters, null, true);
   
       }
   
  
  
  
  1.10      +3 -4      jakarta-tapestry/framework/src/net/sf/tapestry/engine/ResetService.java
  
  Index: ResetService.java
  ===================================================================
  RCS file: /home/cvs/jakarta-tapestry/framework/src/net/sf/tapestry/engine/ResetService.java,v
  retrieving revision 1.9
  retrieving revision 1.10
  diff -u -r1.9 -r1.10
  --- ResetService.java	24 Jan 2003 00:49:33 -0000	1.9
  +++ ResetService.java	27 Jan 2003 16:30:17 -0000	1.10
  @@ -59,7 +59,6 @@
   import javax.servlet.ServletException;
   
   import net.sf.tapestry.ApplicationRuntimeException;
  -import net.sf.tapestry.Gesture;
   import net.sf.tapestry.IComponent;
   import net.sf.tapestry.IEngineServiceView;
   import net.sf.tapestry.IPage;
  @@ -85,7 +84,7 @@
   public class ResetService extends AbstractService
   {
   
  -    public Gesture buildGesture(IRequestCycle cycle, IComponent component, Object[] parameters)
  +    public ILink getLink(IRequestCycle cycle, IComponent component, Object[] parameters)
       {
           if (Tapestry.size(parameters) != 0)
               throw new IllegalArgumentException(
  @@ -94,7 +93,7 @@
           String[] context = new String[1];
           context[0] = component.getPage().getPageName();
   
  -        return assembleGesture(cycle, Tapestry.RESET_SERVICE, context, null, true);
  +        return constructLink(cycle, Tapestry.RESET_SERVICE, context, null, true);
       }
   
       public String getName()
  
  
  
  1.11      +3 -4      jakarta-tapestry/framework/src/net/sf/tapestry/engine/DirectService.java
  
  Index: DirectService.java
  ===================================================================
  RCS file: /home/cvs/jakarta-tapestry/framework/src/net/sf/tapestry/engine/DirectService.java,v
  retrieving revision 1.10
  retrieving revision 1.11
  diff -u -r1.10 -r1.11
  --- DirectService.java	24 Jan 2003 00:49:33 -0000	1.10
  +++ DirectService.java	27 Jan 2003 16:30:17 -0000	1.11
  @@ -60,7 +60,6 @@
   import javax.servlet.http.HttpSession;
   
   import net.sf.tapestry.ApplicationRuntimeException;
  -import net.sf.tapestry.Gesture;
   import net.sf.tapestry.IComponent;
   import net.sf.tapestry.IDirect;
   import net.sf.tapestry.IEngineServiceView;
  @@ -100,7 +99,7 @@
   
       private static final String STATEFUL_OFF = "0";
   
  -    public Gesture buildGesture(IRequestCycle cycle, IComponent component, Object[] parameters)
  +    public ILink getLink(IRequestCycle cycle, IComponent component, Object[] parameters)
       {
   
           // New since 1.0.1, we use the component to determine
  @@ -131,7 +130,7 @@
           context[i++] = componentPage.getPageName();
           context[i++] = component.getIdPath();
   
  -        return assembleGesture(cycle, Tapestry.DIRECT_SERVICE, context, parameters, true);
  +        return constructLink(cycle, Tapestry.DIRECT_SERVICE, context, parameters, true);
       }
   
       public boolean service(IEngineServiceView engine, IRequestCycle cycle, ResponseOutputStream output)
  
  
  
  1.8       +3 -4      jakarta-tapestry/framework/src/net/sf/tapestry/engine/HomeService.java
  
  Index: HomeService.java
  ===================================================================
  RCS file: /home/cvs/jakarta-tapestry/framework/src/net/sf/tapestry/engine/HomeService.java,v
  retrieving revision 1.7
  retrieving revision 1.8
  diff -u -r1.7 -r1.8
  --- HomeService.java	24 Jan 2003 00:49:33 -0000	1.7
  +++ HomeService.java	27 Jan 2003 16:30:17 -0000	1.8
  @@ -58,7 +58,6 @@
   
   import javax.servlet.ServletException;
   
  -import net.sf.tapestry.Gesture;
   import net.sf.tapestry.IComponent;
   import net.sf.tapestry.IEngine;
   import net.sf.tapestry.IEngineServiceView;
  @@ -84,13 +83,13 @@
   public class HomeService extends AbstractService
   {
   
  -    public Gesture buildGesture(IRequestCycle cycle, IComponent component, Object[] parameters)
  +    public ILink getLink(IRequestCycle cycle, IComponent component, Object[] parameters)
       {
           if (Tapestry.size(parameters) != 0)
               throw new IllegalArgumentException(
                   Tapestry.getString("service-no-parameters", Tapestry.HOME_SERVICE));
   
  -        return assembleGesture(cycle, Tapestry.HOME_SERVICE, null, null, true);
  +        return constructLink(cycle, Tapestry.HOME_SERVICE, null, null, true);
       }
   
       public boolean service(
  
  
  
  1.13      +8 -8      jakarta-tapestry/framework/src/net/sf/tapestry/engine/AbstractService.java
  
  Index: AbstractService.java
  ===================================================================
  RCS file: /home/cvs/jakarta-tapestry/framework/src/net/sf/tapestry/engine/AbstractService.java,v
  retrieving revision 1.12
  retrieving revision 1.13
  diff -u -r1.12 -r1.13
  --- AbstractService.java	24 Jan 2003 00:49:33 -0000	1.12
  +++ AbstractService.java	27 Jan 2003 16:30:17 -0000	1.13
  @@ -57,7 +57,6 @@
   import java.io.IOException;
   
   import net.sf.tapestry.ApplicationRuntimeException;
  -import net.sf.tapestry.Gesture;
   import net.sf.tapestry.IEngineService;
   import net.sf.tapestry.IRequestCycle;
   import net.sf.tapestry.RequestContext;
  @@ -86,19 +85,20 @@
   public abstract class AbstractService implements IEngineService
   {
       /**
  -     *  Assembles a URL for the service.
  +     *  Constructs a link for the service.
        *
  -     *  @param the path for the servlet for this Tapestry application
  +     *  @param cycle the request cycle
        *  @param serviceName the name of the service
        *  @param serviceContext context related to the service itself which is added to the URL as-is
  -     *  @param otherContext additional context provided by the component; this is application specific
  -     *  information, and is encoded with {@link URLEncoder#encode(String)} before being added
  +     *  @param parameters additional service parameters provided by the component; 
  +     *  this is application specific information, and is encoded with 
  +     *  {@link URLEncoder#encode(String)} before being added
        *  to the query.
        *  @param stateful if true, the final URL must be encoded with the HttpSession id
        *
        **/
   
  -    protected Gesture assembleGesture(
  +    protected ILink constructLink(
           IRequestCycle cycle,
           String serviceName,
           String[] serviceContext,
  @@ -117,7 +117,7 @@
               throw new ApplicationRuntimeException(ex);
           }
   
  -        return new Gesture(cycle, serviceName, serviceContext, squeezed, stateful);
  +        return new EngineServiceLink(cycle, serviceName, serviceContext, squeezed, stateful);
       }
   
       /**
  
  
  
  1.12      +3 -4      jakarta-tapestry/framework/src/net/sf/tapestry/engine/ActionService.java
  
  Index: ActionService.java
  ===================================================================
  RCS file: /home/cvs/jakarta-tapestry/framework/src/net/sf/tapestry/engine/ActionService.java,v
  retrieving revision 1.11
  retrieving revision 1.12
  diff -u -r1.11 -r1.12
  --- ActionService.java	24 Jan 2003 00:49:33 -0000	1.11
  +++ ActionService.java	27 Jan 2003 16:30:17 -0000	1.12
  @@ -60,7 +60,6 @@
   import javax.servlet.http.HttpSession;
   
   import net.sf.tapestry.ApplicationRuntimeException;
  -import net.sf.tapestry.Gesture;
   import net.sf.tapestry.IAction;
   import net.sf.tapestry.IComponent;
   import net.sf.tapestry.IEngineServiceView;
  @@ -100,7 +99,7 @@
   
       private static final String STATEFUL_OFF = "0";
   
  -    public Gesture buildGesture(IRequestCycle cycle, IComponent component, Object[] parameters)
  +    public ILink getLink(IRequestCycle cycle, IComponent component, Object[] parameters)
       {
           if (parameters == null || parameters.length != 1)
               throw new IllegalArgumentException(
  @@ -129,7 +128,7 @@
   
           serviceContext[i++] = component.getIdPath();
   
  -        return assembleGesture(cycle, Tapestry.ACTION_SERVICE, serviceContext, null, true);
  +        return constructLink(cycle, Tapestry.ACTION_SERVICE, serviceContext, null, true);
       }
   
       public boolean service(
  
  
  
  1.11      +2 -3      jakarta-tapestry/framework/src/net/sf/tapestry/engine/ExternalService.java
  
  Index: ExternalService.java
  ===================================================================
  RCS file: /home/cvs/jakarta-tapestry/framework/src/net/sf/tapestry/engine/ExternalService.java,v
  retrieving revision 1.10
  retrieving revision 1.11
  diff -u -r1.10 -r1.11
  --- ExternalService.java	24 Jan 2003 00:49:33 -0000	1.10
  +++ ExternalService.java	27 Jan 2003 16:30:17 -0000	1.11
  @@ -59,7 +59,6 @@
   import javax.servlet.ServletException;
   
   import net.sf.tapestry.ApplicationRuntimeException;
  -import net.sf.tapestry.Gesture;
   import net.sf.tapestry.IComponent;
   import net.sf.tapestry.IEngineServiceView;
   import net.sf.tapestry.IExternalPage;
  @@ -145,7 +144,7 @@
   public class ExternalService extends AbstractService
   {
   
  -    public Gesture buildGesture(IRequestCycle cycle, IComponent component, Object[] parameters)
  +    public ILink getLink(IRequestCycle cycle, IComponent component, Object[] parameters)
       {
           if (parameters == null || parameters.length == 0)
               throw new ApplicationRuntimeException(
  @@ -157,7 +156,7 @@
           Object[] pageParameters = new Object[parameters.length - 1];
           System.arraycopy(parameters, 1, pageParameters, 0, parameters.length - 1);
   
  -        return assembleGesture(cycle, Tapestry.EXTERNAL_SERVICE, context, pageParameters, true);
  +        return constructLink(cycle, Tapestry.EXTERNAL_SERVICE, context, pageParameters, true);
       }
   
       public boolean service(
  
  
  
  1.1                  jakarta-tapestry/framework/src/net/sf/tapestry/engine/ILink.java
  
  Index: ILink.java
  ===================================================================
  /*
   *  ====================================================================
   *  The Apache Software License, Version 1.1
   *
   *  Copyright (c) 2002 The Apache Software Foundation.  All rights
   *  reserved.
   *
   *  Redistribution and use in source and binary forms, with or without
   *  modification, are permitted provided that the following conditions
   *  are met:
   *
   *  1. Redistributions of source code must retain the above copyright
   *  notice, this list of conditions and the following disclaimer.
   *
   *  2. Redistributions in binary form must reproduce the above copyright
   *  notice, this list of conditions and the following disclaimer in
   *  the documentation and/or other materials provided with the
   *  distribution.
   *
   *  3. The end-user documentation included with the redistribution,
   *  if any, must include the following acknowledgment:
   *  "This product includes software developed by the
   *  Apache Software Foundation (http://www.apache.org/)."
   *  Alternately, this acknowledgment may appear in the software itself,
   *  if and wherever such third-party acknowledgments normally appear.
   *
   *  4. The names "Apache" and "Apache Software Foundation" and
   *  "Apache Tapestry" must not be used to endorse or promote products
   *  derived from this software without prior written permission. For
   *  written permission, please contact apache@apache.org.
   *
   *  5. Products derived from this software may not be called "Apache",
   *  "Apache Tapestry", nor may "Apache" appear in their name, without
   *  prior written permission of the Apache Software Foundation.
   *
   *  THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   *  WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   *  OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   *  DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   *  ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   *  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   *  USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   *  ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   *  OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   *  OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   *  SUCH DAMAGE.
   *  ====================================================================
   *
   *  This software consists of voluntary contributions made by many
   *  individuals on behalf of the Apache Software Foundation.  For more
   *  information on the Apache Software Foundation, please see
   *  <http://www.apache.org/>.
   */
  package net.sf.tapestry.engine;
  
  /**
   *  Define a link that may be generated as part of a page render.  The vast majority
   *  of links are tied to {@link net.sf.tapestry.IEngineService services} and are, in
   *  fact, callbacks.  A small number, such as those generated by
   *  {@link net.sf.tapestry.link.GenericLink} component, are to arbitrary locations.
   *  In addition, ILink differentiates between the path portion of the link, and any
   *  query parameters encoded into a link, primarily to benefit {@link net.sf.tapestry.form.Form},
   *  which needs to encode the query parameters as hidden form fields.
   *
   *  <p>
   *  In addition, an ILink is responsible for
   *  passing constructed URLs through
   *  {@link net.sf.tapestry.IRequestCycle#encodeURL(String)}
   *  as needed.
   * 
   *  @author Howard Lewis Ship
   *  @version $Id: ILink.java,v 1.1 2003/01/27 16:30:17 hlship Exp $
   *  @since 2.4
   * 
   **/
  
  public interface ILink
  {
  	/**
  	 *  Returns the relative URL as a String.  A relative
  	 *  URL may include a leading slash, but omits
  	 *  the scheme, host and port portions of a full URL.
  	 *  
  	 *  @returns the relative URL, with no anchor, but including
  	 *  query parameters.
  	 * 
  	 **/
  	
  	public String getURL();
  	
      /**
       *  Returns the relative URL as a String.  This is used
       *  for most links.
       * 
       *  @param anchor if not null, appended to the URL
       *  @param includeParameters if true, parameters are included
       * 
       **/
  
      public String getURL(String anchor, boolean includeParameters);
  
  	/**
  	 *  Returns the absolute URL as a String, using
  	 *  default scheme, server and port, including
  	 *  parameters, and no anchor.
  	 * 
  	 **/
  	
  	public String getAbsoluteURL();
  
      /**
       *  Returns the absolute URL as a String.  
       * 
       *  @param scheme if not null, overrides the default scheme.
       *  @param server if not null, overrides the default server
       *  @param port if non-zero, overrides the default port
       *  @param anchor if not null, appended to the URL
       *  @param includeParameters if true, parameters are included
       * 
       **/
  
      public String getAbsoluteURL(
          String scheme,
          String server,
          int port,
          String anchor,
          boolean includeParameters);
  
      /**
       * 
       *  Returns an array of parameters names (in
       *  no specified order).
       * 
       *  @see #getParameterValue(String)
       * 
       **/
  
      public String[] getParameterNames();
  
      /**
       *  Returns the values for the named parameter.
       *  
       *  @throws IllegalArgumentException if the
       *  link does not define values for the
       *  specified name.
       * 
       **/
  
      public String[] getParameterValues(String name);
  }
  
  
  
  1.1                  jakarta-tapestry/framework/src/net/sf/tapestry/engine/EngineServiceLink.java
  
  Index: EngineServiceLink.java
  ===================================================================
  /*
   *  ====================================================================
   *  The Apache Software License, Version 1.1
   *
   *  Copyright (c) 2002 The Apache Software Foundation.  All rights
   *  reserved.
   *
   *  Redistribution and use in source and binary forms, with or without
   *  modification, are permitted provided that the following conditions
   *  are met:
   *
   *  1. Redistributions of source code must retain the above copyright
   *  notice, this list of conditions and the following disclaimer.
   *
   *  2. Redistributions in binary form must reproduce the above copyright
   *  notice, this list of conditions and the following disclaimer in
   *  the documentation and/or other materials provided with the
   *  distribution.
   *
   *  3. The end-user documentation included with the redistribution,
   *  if any, must include the following acknowledgment:
   *  "This product includes software developed by the
   *  Apache Software Foundation (http://www.apache.org/)."
   *  Alternately, this acknowledgment may appear in the software itself,
   *  if and wherever such third-party acknowledgments normally appear.
   *
   *  4. The names "Apache" and "Apache Software Foundation" and
   *  "Apache Tapestry" must not be used to endorse or promote products
   *  derived from this software without prior written permission. For
   *  written permission, please contact apache@apache.org.
   *
   *  5. Products derived from this software may not be called "Apache",
   *  "Apache Tapestry", nor may "Apache" appear in their name, without
   *  prior written permission of the Apache Software Foundation.
   *
   *  THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   *  WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   *  OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   *  DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   *  ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   *  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   *  USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   *  ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   *  OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   *  OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   *  SUCH DAMAGE.
   *  ====================================================================
   *
   *  This software consists of voluntary contributions made by many
   *  individuals on behalf of the Apache Software Foundation.  For more
   *  information on the Apache Software Foundation, please see
   *  <http://www.apache.org/>.
   */
  package net.sf.tapestry.engine;
  
  import java.net.URLEncoder;
  import java.util.ArrayList;
  import java.util.List;
  
  import org.apache.commons.lang.builder.ToStringBuilder;
  
  import net.sf.tapestry.IRequestCycle;
  import net.sf.tapestry.RequestContext;
  import net.sf.tapestry.Tapestry;
  
  /**
   *  A EngineServiceLink represents a possible action within the client web browser;
   *  either clicking a link or submitting a form, which is constructed primarily
   *  from the {@link net.sf.tapestry.IEngine#getServletPath() servlet path},
   *  with some additional query parameters.  A full URL for the EngineServiceLink
   *  can be generated, or the query parameters for the EngineServiceLink can be extracted
   *  (separately from the servlet path).  The latter case is used when submitting
   *  constructing {@link net.sf.tapestry.form.Form forms}.
   *
   *  @author Howard Lewis Ship
   *  @version $Id: EngineServiceLink.java,v 1.1 2003/01/27 16:30:17 hlship Exp $
   *  @since 2.4
   * 
   **/
  
  public class EngineServiceLink implements ILink
  {
      private static final int DEFAULT_HTTP_PORT = 80;
  
      private IRequestCycle _cycle;
      private String _serviceName;
      private String _context;
      private String[] _parameters;
      private boolean _stateful;
  
      /**
       *  Creates a new EngineServiceLink.  A EngineServiceLink always names a service to be activated
       *  by the link, has an optional list of service context strings,
       *  an optional list of service parameter strings and may be stateful
       *  or stateless.
       * 
       *  <p>ServiceLink parameter strings may contain any characters.
       * 
       *  <p>ServiceLink context strings must be URL safe, and may not contain
       *  slash ('/') characters.  Typically, only letters, numbers and simple
       *  punctuation ('.', '-', '_', ':') is recommended (no checks are currently made,
       *  however).  Context strings are generally built from page names
       *  and component ids, which are limited to safe characters.
       *  
       *  @param cycle The {@link IRequestCycle} the EngineServiceLink is to be created for.
       *  @param serviceName The name of the service to be invoked by the EngineServiceLink.
       *  @param serviceContext an optional array of strings to be provided
       *  to the service to provide a context for executing the service.  May be null
       *  or empty.  <b>Note: copied, not retained.</b>
       *  @param serviceParameters An array of parameters, may be 
       *  null or empty. <b>Note: retained, not copied.</b>
       *  @param stateful if true, the service which generated the EngineServiceLink
       *  is stateful and expects that the final URL will be passed through
       *  {@link IRequestCycle#encodeURL(String)}.
       **/
  
      public EngineServiceLink(
          IRequestCycle cycle,
          String serviceName,
          String[] serviceContext,
          String[] serviceParameters,
          boolean stateful)
      {
          _cycle = cycle;
          _serviceName = serviceName;
          _context = constructContext(serviceContext);
          _parameters = serviceParameters;
          _stateful = stateful;
      }
  
      private String constructContext(String[] serviceContext)
      {
          int count = Tapestry.size(serviceContext);
  
          if (count == 0)
              return null;
  
          StringBuffer buffer = new StringBuffer();
  
          for (int i = 0; i < count; i++)
          {
              if (i > 0)
                  buffer.append('/');
  
              buffer.append(serviceContext[i]);
          }
  
          return buffer.toString();
      }
  
      public String getURL()
      {
          return getURL(null, true);
      }
  
      public String getURL(String anchor, boolean includeParameters)
      {
          return constructURL(new StringBuffer(), anchor, includeParameters);
      }
  
      public String getAbsoluteURL()
      {
          return getAbsoluteURL(null, null, 0, null, true);
      }
  
      public String getAbsoluteURL(
          String scheme,
          String server,
          int port,
          String anchor,
          boolean includeParameters)
      {
          StringBuffer buffer = new StringBuffer();
          RequestContext context = _cycle.getRequestContext();
  
          if (scheme == null)
              scheme = context.getScheme();
  
          buffer.append(scheme);
          buffer.append("://");
  
          if (server == null)
              server = context.getServerName();
  
          buffer.append(server);
  
          if (port == 0)
              port = context.getServerPort();
  
          if (!(scheme.equals("http") && port == DEFAULT_HTTP_PORT))
          {
              buffer.append(':');
              buffer.append(port);
          }
  
          // Add the servlet path and the rest of the URL & query parameters.
          // The servlet path starts with a leading slash.
  
          return constructURL(buffer, anchor, includeParameters);
      }
  
      private String constructURL(StringBuffer buffer, String anchor, boolean includeParameters)
      {
          buffer.append(_cycle.getEngine().getServletPath());
  
          if (includeParameters)
          {
              buffer.append('?');
              buffer.append(Tapestry.SERVICE_QUERY_PARAMETER_NAME);
              buffer.append('=');
              buffer.append(_serviceName);
  
              if (_context != null)
              {
                  buffer.append('&');
                  buffer.append(Tapestry.CONTEXT_QUERY_PARMETER_NAME);
                  buffer.append('=');
                  buffer.append(_context);
              }
  
              int count = Tapestry.size(_parameters);
  
              for (int i = 0; i < count; i++)
              {
                  buffer.append('&');
  
                  buffer.append(Tapestry.PARAMETERS_QUERY_PARAMETER_NAME);
                  buffer.append('=');
  
                  try
                  {
                      // We use the older, deprecated version of this method, which is compatible
                      // with the JDK 1.2.2.
  
                      String encoded = URLEncoder.encode(_parameters[i]);
  
                      buffer.append(encoded);
                  }
                  catch (Exception ex)
                  {
                      // JDK1.2.2 claims this throws Exception.  It doesn't
                      // and we ignore it.
                  }
              }
          }
  
          if (anchor != null)
          {
              buffer.append('#');
              buffer.append(anchor);
          }
  
          String result = buffer.toString();
  
          if (_stateful)
              result = _cycle.encodeURL(result);
  
          return result;
      }
  
      public String[] getParameterNames()
      {
          List list = new ArrayList();
  
          list.add(Tapestry.SERVICE_QUERY_PARAMETER_NAME);
  
          if (_context != null)
              list.add(Tapestry.CONTEXT_QUERY_PARMETER_NAME);
  
          if (Tapestry.size(_parameters) != 0)
              list.add(Tapestry.PARAMETERS_QUERY_PARAMETER_NAME);
  
          return (String[]) list.toArray(new String[list.size()]);
      }
  
      public String[] getParameterValues(String name)
      {
          if (name.equals(Tapestry.SERVICE_QUERY_PARAMETER_NAME))
          {
              return new String[] { _serviceName };
          }
  
          if (name.equals(Tapestry.CONTEXT_QUERY_PARMETER_NAME))
          {
              return new String[] { _context };
          }
  
          if (name.equals(Tapestry.PARAMETERS_QUERY_PARAMETER_NAME))
          {
              return _parameters;
          }
  
          throw new IllegalArgumentException(
              Tapestry.getString("EngineServiceLink.unknown-parameter-name", name));
  
      }
  
      public String toString()
      {
          ToStringBuilder builder = new ToStringBuilder(this);
  
          builder.append("serviceName", _serviceName);
          builder.append("context", _context);
          builder.append("parameters", _parameters);
          builder.append("stateful", _stateful);
  
          return builder.toString();
      }
  
  }
  
  
  1.11      +6 -5      jakarta-tapestry/framework/src/net/sf/tapestry/asset/AssetService.java
  
  Index: AssetService.java
  ===================================================================
  RCS file: /home/cvs/jakarta-tapestry/framework/src/net/sf/tapestry/asset/AssetService.java,v
  retrieving revision 1.10
  retrieving revision 1.11
  diff -u -r1.10 -r1.11
  --- AssetService.java	24 Jan 2003 00:49:36 -0000	1.10
  +++ AssetService.java	27 Jan 2003 16:30:18 -0000	1.11
  @@ -65,7 +65,6 @@
   import javax.servlet.ServletException;
   
   import net.sf.tapestry.ApplicationRuntimeException;
  -import net.sf.tapestry.Gesture;
   import net.sf.tapestry.IComponent;
   import net.sf.tapestry.IEngineServiceView;
   import net.sf.tapestry.IRequestCycle;
  @@ -73,6 +72,8 @@
   import net.sf.tapestry.ResponseOutputStream;
   import net.sf.tapestry.Tapestry;
   import net.sf.tapestry.engine.AbstractService;
  +import net.sf.tapestry.engine.EngineServiceLink;
  +import net.sf.tapestry.engine.ILink;
   
   /**
    *  A service for building URLs to and accessing {@link IAsset}s.
  @@ -119,14 +120,14 @@
       private static final int BUFFER_SIZE = 10240;
   
       /**
  -     *  Builds a {@link Gesture} for a {@link PrivateAsset}.
  +     *  Builds a {@link ILink} for a {@link PrivateAsset}.
        *
        *  <p>A single parameter is expected, the resource path of the asset
        *  (which is expected to start with a leading slash).
        *
        **/
   
  -    public Gesture buildGesture(IRequestCycle cycle, IComponent component, Object[] parameters)
  +    public ILink getLink(IRequestCycle cycle, IComponent component, Object[] parameters)
       {
           if (Tapestry.size(parameters) != 1)
               throw new ApplicationRuntimeException(
  @@ -134,7 +135,7 @@
   
           // Service is stateless
   
  -        return assembleGesture(cycle, Tapestry.ASSET_SERVICE, null, parameters, false);
  +        return constructLink(cycle, Tapestry.ASSET_SERVICE, null, parameters, false);
       }
   
       public String getName()
  
  
  
  1.12      +4 -4      jakarta-tapestry/framework/src/net/sf/tapestry/asset/PrivateAsset.java
  
  Index: PrivateAsset.java
  ===================================================================
  RCS file: /home/cvs/jakarta-tapestry/framework/src/net/sf/tapestry/asset/PrivateAsset.java,v
  retrieving revision 1.11
  retrieving revision 1.12
  diff -u -r1.11 -r1.12
  --- PrivateAsset.java	24 Jan 2003 00:49:36 -0000	1.11
  +++ PrivateAsset.java	27 Jan 2003 16:30:18 -0000	1.12
  @@ -61,12 +61,12 @@
   import java.util.Map;
   
   import net.sf.tapestry.ApplicationRuntimeException;
  -import net.sf.tapestry.Gesture;
   import net.sf.tapestry.IAsset;
   import net.sf.tapestry.IEngineService;
   import net.sf.tapestry.IRequestCycle;
   import net.sf.tapestry.IResourceResolver;
   import net.sf.tapestry.Tapestry;
  +import net.sf.tapestry.engine.ILink;
   import net.sf.tapestry.util.LocalizedResourceFinder;
   import org.apache.commons.logging.Log;
   import org.apache.commons.logging.LogFactory;
  @@ -129,9 +129,9 @@
   
           IEngineService service = cycle.getEngine().getService(Tapestry.ASSET_SERVICE);
   
  -        Gesture g = service.buildGesture(cycle, null, parameters);
  +        ILink link = service.getLink(cycle, null, parameters);
   
  -        return g.getURL();
  +        return link.getURL();
       }
   
       public InputStream getResourceAsStream(IRequestCycle cycle)
  
  
  
  1.13      +5 -4      jakarta-tapestry/examples/Tutorial/src/tutorial/workbench/chart/ChartService.java
  
  Index: ChartService.java
  ===================================================================
  RCS file: /home/cvs/jakarta-tapestry/examples/Tutorial/src/tutorial/workbench/chart/ChartService.java,v
  retrieving revision 1.12
  retrieving revision 1.13
  diff -u -r1.12 -r1.13
  --- ChartService.java	17 Jan 2003 17:45:31 -0000	1.12
  +++ ChartService.java	27 Jan 2003 16:30:18 -0000	1.13
  @@ -64,7 +64,6 @@
   import com.jrefinery.chart.ChartUtilities;
   import com.jrefinery.chart.JFreeChart;
   
  -import net.sf.tapestry.Gesture;
   import net.sf.tapestry.IComponent;
   import net.sf.tapestry.IEngineServiceView;
   import net.sf.tapestry.IPage;
  @@ -72,6 +71,8 @@
   import net.sf.tapestry.RequestCycleException;
   import net.sf.tapestry.ResponseOutputStream;
   import net.sf.tapestry.engine.AbstractService;
  +import net.sf.tapestry.engine.EngineServiceLink;
  +import net.sf.tapestry.engine.ILink;
   
   /**
    *  ServiceLink that works with a {@link JFreeChart} to dynamically render
  @@ -91,7 +92,7 @@
   
       public static final String SERVICE_NAME = "chart";
   
  -    public Gesture buildGesture(IRequestCycle cycle, IComponent component, Object[] parameters)
  +    public ILink getLink(IRequestCycle cycle, IComponent component, Object[] parameters)
       {
           String[] context;
           String pageName = component.getPage().getPageName();
  @@ -107,7 +108,7 @@
   
           context[0] = pageName;
   
  -        return assembleGesture(cycle, SERVICE_NAME, context, null, true);
  +        return constructLink(cycle, SERVICE_NAME, context, null, true);
       }
   
       public boolean service(IEngineServiceView engine, IRequestCycle cycle, ResponseOutputStream output)
  
  
  
  1.10      +5 -4      jakarta-tapestry/examples/Tutorial/src/tutorial/workbench/chart/ChartAsset.java
  
  Index: ChartAsset.java
  ===================================================================
  RCS file: /home/cvs/jakarta-tapestry/examples/Tutorial/src/tutorial/workbench/chart/ChartAsset.java,v
  retrieving revision 1.9
  retrieving revision 1.10
  diff -u -r1.9 -r1.10
  --- ChartAsset.java	13 Jan 2003 03:33:40 -0000	1.9
  +++ ChartAsset.java	27 Jan 2003 16:30:19 -0000	1.10
  @@ -57,12 +57,13 @@
   import java.io.InputStream;
   import java.util.Locale;
   
  -import net.sf.tapestry.Gesture;
   import net.sf.tapestry.IAsset;
   import net.sf.tapestry.IComponent;
   import net.sf.tapestry.IEngine;
   import net.sf.tapestry.IEngineService;
   import net.sf.tapestry.IRequestCycle;
  +import net.sf.tapestry.engine.EngineServiceLink;
  +import net.sf.tapestry.engine.ILink;
   
   /**
    *  An asset used with the {@link ChartService}.  
  @@ -88,9 +89,9 @@
   
       public String buildURL(IRequestCycle cycle)
       {
  -        Gesture g = _chartService.buildGesture(cycle, _chartProvider, null);
  +        ILink l = _chartService.getLink(cycle, _chartProvider, null);
   
  -        return g.getURL();
  +        return l.getURL();
       }
   
       public InputStream getResourceAsStream(IRequestCycle cycle) 
  
  
  
  1.10      +4 -4      jakarta-tapestry/framework/src/net/sf/tapestry/html/Frame.java
  
  Index: Frame.java
  ===================================================================
  RCS file: /home/cvs/jakarta-tapestry/framework/src/net/sf/tapestry/html/Frame.java,v
  retrieving revision 1.9
  retrieving revision 1.10
  diff -u -r1.9 -r1.10
  --- Frame.java	24 Jan 2003 00:49:36 -0000	1.9
  +++ Frame.java	27 Jan 2003 16:30:19 -0000	1.10
  @@ -55,13 +55,13 @@
   package net.sf.tapestry.html;
   
   import net.sf.tapestry.AbstractComponent;
  -import net.sf.tapestry.Gesture;
   import net.sf.tapestry.IEngine;
   import net.sf.tapestry.IEngineService;
   import net.sf.tapestry.IMarkupWriter;
   import net.sf.tapestry.IRequestCycle;
   import net.sf.tapestry.RequestCycleException;
   import net.sf.tapestry.Tapestry;
  +import net.sf.tapestry.engine.ILink;
   
   /**
    *  Implements a &lt;frame&gt; within a &lt;frameset&gt;.
  @@ -86,10 +86,10 @@
           IEngine engine = cycle.getEngine();
           IEngineService pageService = engine.getService(Tapestry.PAGE_SERVICE);
   
  -        Gesture g = pageService.buildGesture(cycle, this, new String[] { _targetPage });
  +        ILink link = pageService.getLink(cycle, this, new String[] { _targetPage });
   
           writer.beginEmpty("frame");
  -        writer.attribute("src", g.getURL());
  +        writer.attribute("src", link.getURL());
   
           generateAttributes(writer, cycle);
   
  
  
  
  1.16      +24 -12    jakarta-tapestry/framework/src/net/sf/tapestry/html/Rollover.java
  
  Index: Rollover.java
  ===================================================================
  RCS file: /home/cvs/jakarta-tapestry/framework/src/net/sf/tapestry/html/Rollover.java,v
  retrieving revision 1.15
  retrieving revision 1.16
  diff -u -r1.15 -r1.16
  --- Rollover.java	17 Jan 2003 17:40:25 -0000	1.15
  +++ Rollover.java	27 Jan 2003 16:30:19 -0000	1.16
  @@ -70,8 +70,8 @@
   import net.sf.tapestry.ScriptException;
   import net.sf.tapestry.ScriptSession;
   import net.sf.tapestry.Tapestry;
  -import net.sf.tapestry.components.IServiceLink;
  -import net.sf.tapestry.components.ServiceLinkEventType;
  +import net.sf.tapestry.components.ILinkComponent;
  +import net.sf.tapestry.components.LinkEventType;
   
   /**
    *  Combines a link component (such as {@link net.sf.tapestry.link.DirectLink}) 
  @@ -110,7 +110,8 @@
           return asset.buildURL(cycle);
       }
   
  -    protected void renderComponent(IMarkupWriter writer, IRequestCycle cycle) throws RequestCycleException
  +    protected void renderComponent(IMarkupWriter writer, IRequestCycle cycle)
  +        throws RequestCycleException
       {
           // No body, so we skip it all if not rewinding (assumes no side effects on
           // accessors).
  @@ -126,12 +127,17 @@
   
           Body body = Body.get(cycle);
           if (body == null)
  -            throw new RequestCycleException(Tapestry.getString("Rollover.must-be-contained-by-body"), this);
  +            throw new RequestCycleException(
  +                Tapestry.getString("Rollover.must-be-contained-by-body"),
  +                this);
   
  -        IServiceLink serviceLink = (IServiceLink) cycle.getAttribute(IServiceLink.ATTRIBUTE_NAME);
  +        ILinkComponent serviceLink =
  +            (ILinkComponent) cycle.getAttribute(Tapestry.LINK_COMPONENT_ATTRIBUTE_NAME);
   
           if (serviceLink == null)
  -            throw new RequestCycleException(Tapestry.getString("Rollover.must-be-contained-by-link"), this);
  +            throw new RequestCycleException(
  +                Tapestry.getString("Rollover.must-be-contained-by-link"),
  +                this);
   
           boolean linkDisabled = serviceLink.isDisabled();
   
  @@ -193,8 +199,9 @@
               IEngine engine = getPage().getEngine();
               IScriptSource source = engine.getScriptSource();
   
  -            IResourceLocation scriptLocation
  -             = getSpecification().getSpecificationLocation().getRelativeLocation("Rollover.script");
  +            IResourceLocation scriptLocation =
  +                getSpecification().getSpecificationLocation().getRelativeLocation(
  +                    "Rollover.script");
   
               _parsedScript = source.getScript(scriptLocation);
           }
  @@ -202,7 +209,8 @@
           return _parsedScript;
       }
   
  -    private String writeScript(Body body, IServiceLink link, String focusURL, String blurURL) throws ScriptException
  +    private String writeScript(Body body, ILinkComponent link, String focusURL, String blurURL)
  +        throws ScriptException
       {
           String uniqueId = body.getUniqueId();
           String focusImageURL = body.getPreloadedImageReference(focusURL);
  @@ -223,8 +231,12 @@
           // there won't be any timing issues (such as cause
           // bug #113893).
   
  -        link.addEventHandler(ServiceLinkEventType.MOUSE_OVER, (String) symbols.get("onMouseOverName"));
  -        link.addEventHandler(ServiceLinkEventType.MOUSE_OUT, (String) symbols.get("onMouseOutName"));
  +        link.addEventHandler(
  +            LinkEventType.MOUSE_OVER,
  +            (String) symbols.get("onMouseOverName"));
  +        link.addEventHandler(
  +            LinkEventType.MOUSE_OUT,
  +            (String) symbols.get("onMouseOutName"));
   
           String imageName = (String) symbols.get("imageName");
   
  
  
  
  1.18      +4 -4      jakarta-tapestry/framework/src/net/sf/tapestry/html/Shell.java
  
  Index: Shell.java
  ===================================================================
  RCS file: /home/cvs/jakarta-tapestry/framework/src/net/sf/tapestry/html/Shell.java,v
  retrieving revision 1.17
  retrieving revision 1.18
  diff -u -r1.17 -r1.18
  --- Shell.java	24 Jan 2003 00:49:36 -0000	1.17
  +++ Shell.java	27 Jan 2003 16:30:19 -0000	1.18
  @@ -57,7 +57,6 @@
   import java.util.Date;
   
   import net.sf.tapestry.AbstractComponent;
  -import net.sf.tapestry.Gesture;
   import net.sf.tapestry.IAsset;
   import net.sf.tapestry.IEngineService;
   import net.sf.tapestry.IMarkupWriter;
  @@ -66,6 +65,7 @@
   import net.sf.tapestry.IRequestCycle;
   import net.sf.tapestry.RequestCycleException;
   import net.sf.tapestry.Tapestry;
  +import net.sf.tapestry.engine.ILink;
   
   /**
    *  Component for creating a standard 'shell' for a page, which comprises
  @@ -179,12 +179,12 @@
           IEngineService pageService = cycle.getEngine().getService(Tapestry.PAGE_SERVICE);
           String pageName = getPage().getPageName();
   
  -        Gesture g = pageService.buildGesture(cycle, null, new String[] { pageName });
  +        ILink link = pageService.getLink(cycle, null, new String[] { pageName });
   
           StringBuffer buffer = new StringBuffer();
           buffer.append(_refresh);
           buffer.append("; URL=");
  -        buffer.append(g.getAbsoluteURL());
  +        buffer.append(link.getAbsoluteURL());
   
           // Write out the <meta> tag
   
  
  
  
  1.4       +4 -4      jakarta-tapestry/contrib/src/net/sf/tapestry/contrib/inspector/ShowTemplate.java
  
  Index: ShowTemplate.java
  ===================================================================
  RCS file: /home/cvs/jakarta-tapestry/contrib/src/net/sf/tapestry/contrib/inspector/ShowTemplate.java,v
  retrieving revision 1.3
  retrieving revision 1.4
  diff -u -r1.3 -r1.4
  --- ShowTemplate.java	24 Jan 2003 00:49:38 -0000	1.3
  +++ ShowTemplate.java	27 Jan 2003 16:30:19 -0000	1.4
  @@ -58,7 +58,6 @@
   import java.util.Map;
   
   import net.sf.tapestry.BaseComponent;
  -import net.sf.tapestry.Gesture;
   import net.sf.tapestry.IComponent;
   import net.sf.tapestry.IDirect;
   import net.sf.tapestry.IEngineService;
  @@ -68,6 +67,7 @@
   import net.sf.tapestry.ITemplateSource;
   import net.sf.tapestry.RequestCycleException;
   import net.sf.tapestry.Tapestry;
  +import net.sf.tapestry.engine.ILink;
   import net.sf.tapestry.parse.CloseToken;
   import net.sf.tapestry.parse.ComponentTemplate;
   import net.sf.tapestry.parse.LocalizationToken;
  @@ -284,7 +284,7 @@
           // Build a URL to select that component, as if by the captive
           // component itself (it's a Direct).
   
  -        Gesture g = service.buildGesture(getPage().getRequestCycle(), this, context);
  +        ILink link = service.getLink(getPage().getRequestCycle(), this, context);
   
           writer.begin("span");
           writer.attribute("class", "jwc-tag");
  @@ -298,7 +298,7 @@
           writer.attribute("class", "jwc-id");
   
           writer.begin("a");
  -        writer.attribute("href", g.getURL());
  +        writer.attribute("href", link.getURL());
           writer.print(id);
   
           writer.end(); // <a>
  
  
  
  1.4       +4 -4      jakarta-tapestry/contrib/src/net/sf/tapestry/contrib/inspector/InspectorButton.java
  
  Index: InspectorButton.java
  ===================================================================
  RCS file: /home/cvs/jakarta-tapestry/contrib/src/net/sf/tapestry/contrib/inspector/InspectorButton.java,v
  retrieving revision 1.3
  retrieving revision 1.4
  diff -u -r1.3 -r1.4
  --- InspectorButton.java	24 Jan 2003 00:49:38 -0000	1.3
  +++ InspectorButton.java	27 Jan 2003 16:30:20 -0000	1.4
  @@ -58,7 +58,6 @@
   import java.util.Map;
   
   import net.sf.tapestry.BaseComponent;
  -import net.sf.tapestry.Gesture;
   import net.sf.tapestry.IDirect;
   import net.sf.tapestry.IEngine;
   import net.sf.tapestry.IEngineService;
  @@ -71,6 +70,7 @@
   import net.sf.tapestry.ScriptException;
   import net.sf.tapestry.ScriptSession;
   import net.sf.tapestry.Tapestry;
  +import net.sf.tapestry.engine.ILink;
   import net.sf.tapestry.html.Body;
   
   /**
  @@ -131,9 +131,9 @@
           Map symbols = new HashMap();
   
           IEngineService service = engine.getService(Tapestry.DIRECT_SERVICE);
  -        Gesture g = service.buildGesture(cycle, this, null);
  +        ILink link = service.getLink(cycle, this, null);
   
  -        symbols.put("URL", g.getURL());
  +        symbols.put("URL", link.getURL());
   
           ScriptSession scriptSession = null;
   
  
  
  
  1.14      +10 -1     jakarta-tapestry/framework/src/net/sf/tapestry/Tapestry.java
  
  Index: Tapestry.java
  ===================================================================
  RCS file: /home/cvs/jakarta-tapestry/framework/src/net/sf/tapestry/Tapestry.java,v
  retrieving revision 1.13
  retrieving revision 1.14
  diff -u -r1.13 -r1.14
  --- Tapestry.java	24 Jan 2003 00:49:34 -0000	1.13
  +++ Tapestry.java	27 Jan 2003 16:30:20 -0000	1.14
  @@ -240,6 +240,15 @@
   	public static final String DEFAULT_TEMPLATE_EXTENSION = "html";
   	
       /**
  +     *  The name of an {@link net.sf.tapestry.IRequestCycle} attribute in which the
  +     *  currently rendering {@link net.sf.tapestry.components.ILinkComponent}
  +     *  is stored.  Link components do not nest.
  +     *
  +     **/
  +
  +    public static final String LINK_COMPONENT_ATTRIBUTE_NAME = "net.sf.tapestry.active-link-component";
  +    	
  +    /**
        *  Prevent instantiation.
        *
        **/
  
  
  
  1.15      +18 -15    jakarta-tapestry/framework/src/net/sf/tapestry/IEngineService.java
  
  Index: IEngineService.java
  ===================================================================
  RCS file: /home/cvs/jakarta-tapestry/framework/src/net/sf/tapestry/IEngineService.java,v
  retrieving revision 1.14
  retrieving revision 1.15
  diff -u -r1.14 -r1.15
  --- IEngineService.java	24 Jan 2003 00:49:34 -0000	1.14
  +++ IEngineService.java	27 Jan 2003 16:30:21 -0000	1.15
  @@ -58,10 +58,12 @@
   
   import javax.servlet.ServletException;
   
  +import net.sf.tapestry.engine.*;
  +
   /**
    *  A service, provided by the {@link IEngine}, for its pages and/or components.  
    *  Services are
  - *  responsible for constructing {@link Gesture}s (an encoding of URLs)
  + *  responsible for constructing {@link EngineServiceLink}s (an encoding of URLs)
    *  to represent dynamic application behavior, and for
    *  parsing those URLs when a subsequent request involves them.
    *
  @@ -79,56 +81,56 @@
        *
        **/
   
  -    public final static String ACTION_SERVICE = "action";
  +    public final static String ACTION_SERVICE = Tapestry.ACTION_SERVICE;
   
       /**
        *  @deprecated To be removed in 2.5.  Use {@link Tapestry#DIRECT_SERVICE} instead.
        *
        **/
   
  -    public final static String DIRECT_SERVICE = "direct";
  +    public final static String DIRECT_SERVICE = Tapestry.DIRECT_SERVICE;
   
       /**
        *  @deprecated To be removed in 2.5.  Use {@link Tapestry#EXTERNAL_SERVICE} instead.
        *
        **/
   
  -    public final static String EXTERNAL_SERVICE = "external";
  +    public final static String EXTERNAL_SERVICE = Tapestry.EXTERNAL_SERVICE;
   
       /**
        *  @deprecated To be removed in 2.5.  Use {@link Tapestry#PAGE_SERVICE} instead.
        *
        **/
   
  -    public final static String PAGE_SERVICE = "page";
  +    public final static String PAGE_SERVICE = Tapestry.PAGE_SERVICE;
   
       /**
        *  @deprecated To be removed in 2.5.  Use {@link Tapestry#HOME_SERVICE} instead.
        *
        **/
   
  -    public final static String HOME_SERVICE = "home";
  +    public final static String HOME_SERVICE = Tapestry.HOME_SERVICE;
   
       /**
        *  @deprecated To be removed in 2.5.  Use {@link Tapestry#RESTART_SERVICE} instead.
        *
        **/
   
  -    public static final String RESTART_SERVICE = "restart";
  +    public static final String RESTART_SERVICE = Tapestry.RESTART_SERVICE;
   
       /**
        *  @deprecated To be removed in 2.5.  Use {@link Tapestry#ASSET_SERVICE} instead.
        *
        **/
   
  -    public static final String ASSET_SERVICE = "asset";
  +    public static final String ASSET_SERVICE = Tapestry.ASSET_SERVICE;
   
       /**
        *  @deprecated To be removed in 2.5.  Use {@link Tapestry#RESET_SERVICE} instead.
        *
        **/
   
  -    public static final String RESET_SERVICE = "reset";
  +    public static final String RESET_SERVICE = Tapestry.RESET_SERVICE;
   
       /**
        *  @deprecated To be removed in 2.5.  Use 
  @@ -136,14 +138,14 @@
        *
        **/
   
  -    public static final String SERVICE_QUERY_PARAMETER_NAME = "service";
  +    public static final String SERVICE_QUERY_PARAMETER_NAME = Tapestry.SERVICE_QUERY_PARAMETER_NAME;
   
       /**
        *  @deprecated To be removed in 2.5.  Use {@link Tapestry#CONTEXT_QUERY_PARMETER_NAME} instead.
        *
        **/
   
  -    public static final String CONTEXT_QUERY_PARMETER_NAME = "context";
  +    public static final String CONTEXT_QUERY_PARMETER_NAME = Tapestry.CONTEXT_QUERY_PARMETER_NAME;
   
       /**
        *  @deprecated To be removed in 2.5.  Use 
  @@ -151,7 +153,8 @@
        *
        **/
   
  -    public static final String PARAMETERS_QUERY_PARAMETER_NAME = "sp";
  +    public static final String PARAMETERS_QUERY_PARAMETER_NAME =
  +        Tapestry.PARAMETERS_QUERY_PARAMETER_NAME;
   
       /**
        *  Builds a URL for a service.  This is performed during the
  @@ -162,13 +165,13 @@
        *  @param component The component requesting the URL.  Generally, the
        *  service context is established from the component.
        *  @param parameters Additional parameters specific to the
  -     *  component requesting the Gesture.
  +     *  component requesting the EngineServiceLink.
        *  @return The URL for the service.  The URL will have to be encoded
        *  via {@link HttpServletResponse#encodeURL(java.lang.String)}.
        *
        **/
   
  -    public Gesture buildGesture(IRequestCycle cycle, IComponent component, Object[] parameters);
  +    public ILink getLink(IRequestCycle cycle, IComponent component, Object[] parameters);
   
       /**
        *  Perform the service, interpreting the URL (from the
  
  
  
  1.41      +6 -6      jakarta-tapestry/framework/src/net/sf/tapestry/TapestryStrings.properties
  
  Index: TapestryStrings.properties
  ===================================================================
  RCS file: /home/cvs/jakarta-tapestry/framework/src/net/sf/tapestry/TapestryStrings.properties,v
  retrieving revision 1.40
  retrieving revision 1.41
  diff -u -r1.40 -r1.41
  --- TapestryStrings.properties	24 Jan 2003 00:49:34 -0000	1.40
  +++ TapestryStrings.properties	27 Jan 2003 16:30:21 -0000	1.41
  @@ -54,8 +54,6 @@
   
   BodylessComponentException.message=This component may not have a body.
   
  -Gesture.unknown-parameter-name=Unknown parameter name ''{0}''.
  -
   NoSuchComponentException.message=Component {0} does not contain a component {1}.
   
   RenderOnlyPropertyException.message=Property {0} of {1} may only be accessed while the component is rendering.
  @@ -153,6 +151,8 @@
   DirectService.component-wrong-type=Component {0} does not implement the IDirect interface.
   DirectService.stale-session-exception=Component {0} is stateful, but the HttpSession has expired (or has not yet been created).
   
  +EngineServiceLink.unknown-parameter-name=Unknown parameter name ''{0}''.
  +
   Namespace.no-such-page=Page ''{0}'' not found in {1}.
   Namespace.no-such-component-type=Component ''{0}'' not found in {1}.
   Namespace.application-namespace=application namespace
  @@ -216,7 +216,7 @@
   InsertText.conversion-error=Error converting text to lines (for InsertText component).
   
   Rollover.must-be-contained-by-body=Rollover components must be contained within a Body component.
  -Rollover.must-be-contained-by-link=Rollover components must be contained within an IServiceLink component.
  +Rollover.must-be-contained-by-link=Rollover components must be contained within an ILinkComponent.
   
   Script.must-be-contained-by-body=Script components must be contained within a Body component.
   
  @@ -230,8 +230,8 @@
   
   GestureLink.missing-service=No engine service name {0}.
   
  -AbstractServiceLink.no-nesting=IServiceLink components may not be nested.
  -AbstractServiceLink.events-need-body=A link component with multiple functions for a single event type must be contained within a Body.
  +AbstractLinkComponent.no-nesting=ILinkComponents may not be nested.
  +AbstractLinkComponent.events-need-body=A link component with multiple functions for a single event type must be contained within a Body.
   
   # net.sf.tapestry.listener
   
  
  
  
  1.25      +14 -13    jakarta-tapestry/framework/src/net/sf/tapestry/form/Form.java
  
  Index: Form.java
  ===================================================================
  RCS file: /home/cvs/jakarta-tapestry/framework/src/net/sf/tapestry/form/Form.java,v
  retrieving revision 1.24
  retrieving revision 1.25
  diff -u -r1.24 -r1.25
  --- Form.java	24 Jan 2003 00:49:38 -0000	1.24
  +++ Form.java	27 Jan 2003 16:30:22 -0000	1.25
  @@ -61,7 +61,6 @@
   import java.util.Map;
   
   import net.sf.tapestry.AbstractComponent;
  -import net.sf.tapestry.Gesture;
   import net.sf.tapestry.IActionListener;
   import net.sf.tapestry.IBinding;
   import net.sf.tapestry.IComponent;
  @@ -76,6 +75,8 @@
   import net.sf.tapestry.RequestCycleException;
   import net.sf.tapestry.StaleLinkException;
   import net.sf.tapestry.Tapestry;
  +import net.sf.tapestry.engine.EngineServiceLink;
  +import net.sf.tapestry.engine.ILink;
   import net.sf.tapestry.event.PageDetachListener;
   import net.sf.tapestry.event.PageEvent;
   import net.sf.tapestry.html.Body;
  @@ -328,14 +329,14 @@
   
           _rewinding = rewound;
   
  -        Gesture g = getGesture(cycle, actionId);
  +        ILink link = getLink(cycle, actionId);
   
           if (renderForm)
           {
               writer.begin("form");
               writer.attribute("method", (_method == null) ? "post" : _method);
               writer.attribute("name", _name);
  -            writer.attribute("action", g.getBareURL());
  +            writer.attribute("action", link.getURL(null, false));
   
               generateAttributes(writer, cycle);
               writer.println();
  @@ -344,7 +345,7 @@
           // Write the hidden's, or at least, reserve the query parameters
           // required by the Gesture.
   
  -        writeGestureParameters(writer, g, !renderForm);
  +        writeLinkParameters(writer, link, !renderForm);
   
           _allocatedIdIndex = 0;
   
  @@ -575,14 +576,14 @@
       }
   
       /**
  -     *  Builds the Gesture for the form, using either the direct or
  +     *  Builds the EngineServiceLink for the form, using either the direct or
        *  action service. 
        *
        *  @since 1.0.3
        *
        **/
   
  -    private Gesture getGesture(IRequestCycle cycle, String actionId)
  +    private ILink getLink(IRequestCycle cycle, String actionId)
       {
           String serviceName = null;
   
  @@ -596,12 +597,12 @@
   
           // A single service parameter is used to store the actionId.
   
  -        return service.buildGesture(cycle, this, new String[] { actionId });
  +        return service.getLink(cycle, this, new String[] { actionId });
       }
   
  -    private void writeGestureParameters(IMarkupWriter writer, Gesture g, boolean reserveOnly)
  +    private void writeLinkParameters(IMarkupWriter writer, ILink link, boolean reserveOnly)
       {
  -        String[] names = g.getParameterNames();
  +        String[] names = link.getParameterNames();
           int count = Tapestry.size(names);
   
           for (int i = 0; i < count; i++)
  @@ -614,7 +615,7 @@
               _elementIdAllocator.allocateId(name);
   
               if (!reserveOnly)
  -                writeHiddenFieldsForParameter(writer, g, name);
  +                writeHiddenFieldsForParameter(writer, link, name);
           }
       }
   
  @@ -625,10 +626,10 @@
   
       private void writeHiddenFieldsForParameter(
           IMarkupWriter writer,
  -        Gesture g,
  +        ILink link,
           String parameterName)
       {
  -        String[] values = g.getParameterValues(parameterName);
  +        String[] values = link.getParameterValues(parameterName);
   
           for (int i = 0; i < values.length; i++)
           {
  
  
  
  1.1                  jakarta-tapestry/framework/src/net/sf/tapestry/components/ILinkComponent.java
  
  Index: ILinkComponent.java
  ===================================================================
  /*
   *  ====================================================================
   *  The Apache Software License, Version 1.1
   *
   *  Copyright (c) 2002 The Apache Software Foundation.  All rights
   *  reserved.
   *
   *  Redistribution and use in source and binary forms, with or without
   *  modification, are permitted provided that the following conditions
   *  are met:
   *
   *  1. Redistributions of source code must retain the above copyright
   *  notice, this list of conditions and the following disclaimer.
   *
   *  2. Redistributions in binary form must reproduce the above copyright
   *  notice, this list of conditions and the following disclaimer in
   *  the documentation and/or other materials provided with the
   *  distribution.
   *
   *  3. The end-user documentation included with the redistribution,
   *  if any, must include the following acknowledgment:
   *  "This product includes software developed by the
   *  Apache Software Foundation (http://www.apache.org/)."
   *  Alternately, this acknowledgment may appear in the software itself,
   *  if and wherever such third-party acknowledgments normally appear.
   *
   *  4. The names "Apache" and "Apache Software Foundation" and
   *  "Apache Tapestry" must not be used to endorse or promote products
   *  derived from this software without prior written permission. For
   *  written permission, please contact apache@apache.org.
   *
   *  5. Products derived from this software may not be called "Apache",
   *  "Apache Tapestry", nor may "Apache" appear in their name, without
   *  prior written permission of the Apache Software Foundation.
   *
   *  THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   *  WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   *  OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   *  DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   *  ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   *  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   *  USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   *  ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   *  OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   *  OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   *  SUCH DAMAGE.
   *  ====================================================================
   *
   *  This software consists of voluntary contributions made by many
   *  individuals on behalf of the Apache Software Foundation.  For more
   *  information on the Apache Software Foundation, please see
   *  <http://www.apache.org/>.
   */
  package net.sf.tapestry.components;
  
  import net.sf.tapestry.IComponent;
  import net.sf.tapestry.IMarkupWriter;
  import net.sf.tapestry.IRequestCycle;
  import net.sf.tapestry.RequestCycleException;
  import net.sf.tapestry.engine.EngineServiceLink;
  import net.sf.tapestry.engine.ILink;
  
  /**
   *  A component that renders an HTML &lt;a&gt; element.  It exposes some
   *  properties to the components it wraps.  This is basically to facilitate
   *  the {@link net.sf.tapestry.html.Rollover} component.
   *
   *  @author Howard Lewis Ship
   *  @version $Id: ILinkComponent.java,v 1.1 2003/01/27 16:30:22 hlship Exp $
   * 
   **/
  
  public interface ILinkComponent extends IComponent
  {
  
      /**
       *  Returns whether this service link component is enabled or disabled.
       *
       *  @since 0.2.9
       *
       **/
  
      public boolean isDisabled();
  
      /**
       *  Adds a new event handler.  When the event occurs, the JavaScript function
       *  specified is executed.  Multiple functions can be specified, in which case
       *  all of them are executed.
       *
       *  <p>This was created for use by
       *  {@link net.sf.tapestry.html.Rollover} to set mouse over and mouse out handlers on
       *  the {@link ILinkComponent} that wraps it, but can be used for
       *  many other things as well.
       *
       *  @since 0.2.9
       **/
  
      public void addEventHandler(LinkEventType type, String functionName);
      
      /**
       *  Invoked by the {@link net.sf.tapestry.link.ILinkRenderer} (if
       *  the link is not disabled) to provide a
       *  {@link net.sf.tapestry.EngineServiceLink} that the renderer can convert
       *  into a URL.
       * 
       **/
      
      public ILink getLink(IRequestCycle cycle)
      throws RequestCycleException;
      
      /**
       *  Invoked (by the {@link net.sf.tapestry.link.ILinkRenderer})
       *  to make the link render any additional attributes.  These
       *  are informal parameters, plus any attributes related to events.
       *  This is only invoked for non-disabled links.
       * 
       *  @since 2.4
       * 
       **/
      
      public void renderAdditionalAttributes(IMarkupWriter writer, IRequestCycle cycle)
      throws RequestCycleException;
  }
  
  
  1.1                  jakarta-tapestry/framework/src/net/sf/tapestry/components/LinkEventType.java
  
  Index: LinkEventType.java
  ===================================================================
  /*
   *  ====================================================================
   *  The Apache Software License, Version 1.1
   *
   *  Copyright (c) 2002 The Apache Software Foundation.  All rights
   *  reserved.
   *
   *  Redistribution and use in source and binary forms, with or without
   *  modification, are permitted provided that the following conditions
   *  are met:
   *
   *  1. Redistributions of source code must retain the above copyright
   *  notice, this list of conditions and the following disclaimer.
   *
   *  2. Redistributions in binary form must reproduce the above copyright
   *  notice, this list of conditions and the following disclaimer in
   *  the documentation and/or other materials provided with the
   *  distribution.
   *
   *  3. The end-user documentation included with the redistribution,
   *  if any, must include the following acknowledgment:
   *  "This product includes software developed by the
   *  Apache Software Foundation (http://www.apache.org/)."
   *  Alternately, this acknowledgment may appear in the software itself,
   *  if and wherever such third-party acknowledgments normally appear.
   *
   *  4. The names "Apache" and "Apache Software Foundation" and
   *  "Apache Tapestry" must not be used to endorse or promote products
   *  derived from this software without prior written permission. For
   *  written permission, please contact apache@apache.org.
   *
   *  5. Products derived from this software may not be called "Apache",
   *  "Apache Tapestry", nor may "Apache" appear in their name, without
   *  prior written permission of the Apache Software Foundation.
   *
   *  THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   *  WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   *  OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   *  DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   *  ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   *  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   *  USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   *  ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   *  OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   *  OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   *  SUCH DAMAGE.
   *  ====================================================================
   *
   *  This software consists of voluntary contributions made by many
   *  individuals on behalf of the Apache Software Foundation.  For more
   *  information on the Apache Software Foundation, please see
   *  <http://www.apache.org/>.
   */
  package net.sf.tapestry.components;
  
  import org.apache.commons.lang.enum.Enum;
  
  /**
   *  Different types of JavaScript events that an {@link ILinkComponent}
   *  can provide handlers for.
   *
   *  @author Howard Lewis Ship
   *  @version $Id: LinkEventType.java,v 1.1 2003/01/27 16:30:22 hlship Exp $
   *  @since 0.2.9
   *
   **/
  
  public class LinkEventType extends Enum
  {
      private String _attributeName;
  
      /**
       *  Type for <code>onMouseOver</code>.  This may also be called "focus".
       *
       **/
  
      public static final LinkEventType MOUSE_OVER = new LinkEventType("MOUSE_OVER", "onMouseOver");
  
      /**
       * Type for <code>onMouseOut</code>.  This may also be called "blur".
       *
       **/
  
      public static final LinkEventType MOUSE_OUT = new LinkEventType("MOUSE_OUT", "onMouseOut");
  
      /**
       * Type for <code>onClick</code>.
       *
       * @since 1.0.1
       *
       **/
  
      public static final LinkEventType CLICK = new LinkEventType("CLICK", "onClick");
  
      /**
       * Type for <code>onDblClick</code>.
       *
       * @since 1.0.1
       *
       **/
  
      public static final LinkEventType DOUBLE_CLICK =
          new LinkEventType("DOUBLE_CLICK", "onDblClick");
  
      /**
       * Type for <code>onMouseDown</code>.
       *
       * @since 1.0.1.
       *
       **/
  
      public static final LinkEventType MOUSE_DOWN = new LinkEventType("MOUSE_DOWN", "onMouseDown");
  
      /**
       * Type for <code>onMouseUp</code>.
       *
       * @since 1.0.1
       *
       **/
  
      public static final LinkEventType MOUSE_UP = new LinkEventType("MOUSE_UP", "onMouseUp");
  
      /**
       *  Constructs a new type of event.  The name should match the
       *  static final variable (i.e., MOUSE_OVER) and the attributeName
       *  is the name of the HTML attribute to be managed (i.e., "onMouseOver").
       *
       *  <p>This method is protected so that subclasses can be created
       *  to provide additional managed event types.
       **/
  
      protected LinkEventType(String name, String attributeName)
      {
          super(name);
  
          _attributeName = attributeName;
      }
  
      /**
       *  Returns the name of the HTML attribute corresponding to this
       *  type.
       *
       **/
  
      public String getAttributeName()
      {
          return _attributeName;
      }
  }
  
  

Mime
View raw message