You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@tapestry.apache.org by Warner Onstine <sw...@warneronstine.com> on 2004/10/07 22:37:24 UTC

friendly urls?

What happened with incorporating the friendly urls patch? I haven't 
seen anything wizz by on the commits.

-warner


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


Re: friendly urls?

Posted by David Taylor <Da...@ExtensiaTech.com>.
Very Nice!  I had the same idea but hadn't yet worked through the 
implementation details.
I am currently using a slightly modified version of the original hack 
for a couple of web apps.
Aside from the path separator issue, I was able to package all of the 
friendly url changes into
a jar that I simply include in my projects.

Tapestry is the best!

David

Mikaël Cluseau wrote:

> I forgot to mention that you will have to map "*.tap" and "*.tdo" to 
> your ApplicationServlet (if you don't overide the default suffixes).
>
> Here is another patch which changes "." to "/" in page names, so that 
> you don't break the default Tapestry naming conventions but can 
> simulate folders.
>
> Mikael.
>
>
> __________ NOD32 1.895 (20041014) Information __________
>
> This message was checked by NOD32 antivirus system.
> http://www.nod32.com
>
>------------------------------------------------------------------------
>
>Index: .classpath
>===================================================================
>RCS file: /home/cvspublic/jakarta-tapestry/.classpath,v
>retrieving revision 1.41.2.1
>diff -u -r1.41.2.1 .classpath
>--- .classpath	28 Jun 2004 22:16:46 -0000	1.41.2.1
>+++ .classpath	15 Oct 2004 12:17:55 -0000
>@@ -1,32 +1,32 @@
>-<?xml version="1.0" encoding="UTF-8"?>
>-<classpath>
>-    <classpathentry kind="var" path="JRE_LIB" sourcepath="JRE_SRC"/>
>-    <classpathentry kind="lib" path="config"/>
>-    <classpathentry kind="src" path="framework/src"/>
>-    <classpathentry kind="src" path="contrib/src"/>
>-    <classpathentry kind="src" path="junit/src"/>
>-    <classpathentry kind="src" path="examples/VlibBeans/src"/>
>-    <classpathentry kind="src" path="examples/Vlib/src"/>
>-    <classpathentry kind="src" path="examples/Workbench/src"/>
>-    <classpathentry kind="src" path="examples/wap/src"/>
>-    <classpathentry exported="true" kind="lib" path="lib/ext/jakarta-oro-2.0.6.jar"/>
>-    <classpathentry exported="true" kind="lib" path="lib/ext/commons-logging-1.0.2.jar"/>
>-    <classpathentry exported="true" kind="lib" path="lib/ext/commons-lang-1.0.jar"/>
>-    <classpathentry exported="true" kind="lib" path="lib/ext/bsf-2.3.0.jar"/>
>-    <classpathentry kind="lib" path="ext-dist/jdom-b8.jar"/>
>-    <classpathentry kind="lib" path="ext-dist/junit.jar"/>
>-    <classpathentry exported="true" kind="lib" path="lib/ext/commons-beanutils-1.6.1.jar"/>
>-    <classpathentry kind="lib" path="examples/Workbench/lib/jCharts-0.6.0.jar"/>
>-    <classpathentry exported="true" kind="lib" path="lib/ext/commons-collections-2.1.jar"/>
>-    <classpathentry kind="lib" path="lib/ext/commons-fileupload-1.0.jar"/>
>-    <classpathentry exported="true" kind="lib" path="lib/ext/javassist-2.5.1.jar"/>
>-    <classpathentry exported="true" kind="lib" path="lib/ext/commons-digester-1.5.jar"/>
>-    <classpathentry kind="lib" path="lib/ext/commons-codec-1.2.jar"/>
>-    <classpathentry kind="lib" path="lib/ext/ognl-2.6.3.jar"/>
>-    <classpathentry kind="lib" path="lib/j2ee/geronimo-ejb.jar"/>
>-    <classpathentry kind="lib" path="lib/j2ee/jsp-api.jar"/>
>-    <classpathentry exported="true" kind="lib" path="lib/j2ee/servlet-api.jar"/>
>-    <classpathentry kind="var" path="JYTHON_DIR/jython.jar"/>
>-    <classpathentry kind="lib" path="lib/runtime/log4j-1.2.6.jar"/>
>-    <classpathentry kind="output" path="bin"/>
>-</classpath>
>+<?xml version="1.0" encoding="UTF-8"?>
>+<classpath>
>+	<classpathentry sourcepath="JRE_SRC" kind="var" path="JRE_LIB"/>
>+	<classpathentry kind="lib" path="config"/>
>+	<classpathentry kind="src" path="framework/src"/>
>+	<classpathentry kind="src" path="contrib/src"/>
>+	<classpathentry kind="src" path="junit/src"/>
>+	<classpathentry kind="src" path="examples/VlibBeans/src"/>
>+	<classpathentry kind="src" path="examples/Vlib/src"/>
>+	<classpathentry kind="src" path="examples/Workbench/src"/>
>+	<classpathentry kind="src" path="examples/wap/src"/>
>+	<classpathentry exported="true" kind="lib" path="lib/ext/jakarta-oro-2.0.6.jar"/>
>+	<classpathentry exported="true" kind="lib" path="lib/ext/commons-logging-1.0.2.jar"/>
>+	<classpathentry exported="true" kind="lib" path="lib/ext/commons-lang-1.0.jar"/>
>+	<classpathentry exported="true" kind="lib" path="lib/ext/bsf-2.3.0.jar"/>
>+	<classpathentry kind="lib" path="ext-dist/junit.jar"/>
>+	<classpathentry exported="true" kind="lib" path="lib/ext/commons-beanutils-1.6.1.jar"/>
>+	<classpathentry kind="lib" path="examples/Workbench/lib/jCharts-0.6.0.jar"/>
>+	<classpathentry exported="true" kind="lib" path="lib/ext/commons-collections-2.1.jar"/>
>+	<classpathentry kind="lib" path="lib/ext/commons-fileupload-1.0.jar"/>
>+	<classpathentry exported="true" kind="lib" path="lib/ext/javassist-2.5.1.jar"/>
>+	<classpathentry exported="true" kind="lib" path="lib/ext/commons-digester-1.5.jar"/>
>+	<classpathentry kind="lib" path="lib/ext/commons-codec-1.2.jar"/>
>+	<classpathentry kind="lib" path="lib/ext/ognl-2.6.3.jar"/>
>+	<classpathentry kind="lib" path="lib/j2ee/geronimo-ejb.jar"/>
>+	<classpathentry kind="lib" path="lib/j2ee/jsp-api.jar"/>
>+	<classpathentry exported="true" kind="lib" path="lib/j2ee/servlet-api.jar"/>
>+	<classpathentry kind="var" path="JYTHON_DIR/jython.jar"/>
>+	<classpathentry kind="lib" path="lib/runtime/log4j-1.2.6.jar"/>
>+	<classpathentry kind="lib" path="ext-dist/jdom-1.0.jar"/>
>+	<classpathentry kind="output" path="bin"/>
>+</classpath>
>Index: config/common.properties
>===================================================================
>RCS file: /home/cvspublic/jakarta-tapestry/config/Attic/common.properties,v
>retrieving revision 1.31.2.1
>diff -u -r1.31.2.1 common.properties
>--- config/common.properties	29 Jul 2004 15:50:06 -0000	1.31.2.1
>+++ config/common.properties	15 Oct 2004 12:17:55 -0000
>@@ -52,11 +52,11 @@
> junit.loc=http://telia.dl.sourceforge.net/sourceforge/junit/junit3.8.1.zip
> 
> # ----- JDOM Library, version b8 -----
>-jdom.home=${ext.download.dir}/jdom-b8
>+jdom.home=${ext.download.dir}/jdom-1.0
> jdom.lib=${jdom.home}
> jdom.jar=${jdom.lib}/build/jdom.jar
>-jdom.ext.jar=${ext.dist.dir}/jdom-b8.jar
>-jdom.loc=http://www.jdom.org/dist/binary/jdom-b8.tar.gz
>+jdom.ext.jar=${ext.dist.dir}/jdom-1.0.jar
>+jdom.loc=http://www.jdom.org/dist/binary/jdom-1.0.tar.gz
> 
> # ----- McKoi Pure Java Database, version 1.0.2 -----
> mckoi.home=${ext.download.dir}/mckoi1.0.2
>Index: framework/src/org/apache/tapestry/Tapestry.java
>===================================================================
>RCS file: /home/cvspublic/jakarta-tapestry/framework/src/org/apache/tapestry/Attic/Tapestry.java,v
>retrieving revision 1.24.2.1
>diff -u -r1.24.2.1 Tapestry.java
>--- framework/src/org/apache/tapestry/Tapestry.java	1 Sep 2004 13:18:38 -0000	1.24.2.1
>+++ framework/src/org/apache/tapestry/Tapestry.java	15 Oct 2004 12:18:04 -0000
>@@ -204,7 +204,7 @@
>      *
>      **/
> 
>-    public static final String SERVICE_QUERY_PARAMETER_NAME = "service";
>+    public static final String SERVICE_QUERY_PARAMETER_NAME = "sv";
> 
>     /**
>      *  The query parameter for application specific parameters to the
>Index: framework/src/org/apache/tapestry/asset/AssetService.java
>===================================================================
>RCS file: /home/cvspublic/jakarta-tapestry/framework/src/org/apache/tapestry/asset/Attic/AssetService.java,v
>retrieving revision 1.8
>diff -u -r1.8 AssetService.java
>--- framework/src/org/apache/tapestry/asset/AssetService.java	19 Feb 2004 17:38:09 -0000	1.8
>+++ framework/src/org/apache/tapestry/asset/AssetService.java	15 Oct 2004 12:18:05 -0000
>@@ -29,6 +29,8 @@
> import org.apache.tapestry.IRequestCycle;
> import org.apache.tapestry.Tapestry;
> import org.apache.tapestry.engine.AbstractService;
>+import org.apache.tapestry.engine.BaseEngine;
>+import org.apache.tapestry.engine.EngineServiceLink;
> import org.apache.tapestry.engine.IEngineServiceView;
> import org.apache.tapestry.engine.ILink;
> import org.apache.tapestry.request.ResponseOutputStream;
>@@ -82,16 +84,16 @@
>      *  (which is expected to start with a leading slash).
>      *
>      **/
>-
>-    public ILink getLink(IRequestCycle cycle, IComponent component, Object[] parameters)
>+    public ILink getLink(IRequestCycle requestCycle, IComponent component, Object[] parameters)
>     {
>         if (Tapestry.size(parameters) != 1)
>-            throw new ApplicationRuntimeException(
>-                Tapestry.format("service-single-parameter", Tapestry.ASSET_SERVICE));
>-
>-        // Service is stateless
>-
>-        return constructLink(cycle, Tapestry.ASSET_SERVICE, null, parameters, false);
>+        {
>+            throw new ApplicationRuntimeException(Tapestry.format("service-single-parameter", Tapestry.ASSET_SERVICE));
>+        }
>+        
>+        String suffix = BaseEngine.getServiceUrlSuffix(requestCycle.getEngine().getSpecification());
>+        
>+        return new EngineServiceLink(requestCycle, Tapestry.ASSET_SERVICE + suffix, null, parameters);
>     }
> 
>     public String getName()
>Index: framework/src/org/apache/tapestry/engine/AbstractService.java
>===================================================================
>RCS file: /home/cvspublic/jakarta-tapestry/framework/src/org/apache/tapestry/engine/Attic/AbstractService.java,v
>retrieving revision 1.5
>diff -u -r1.5 AbstractService.java
>--- framework/src/org/apache/tapestry/engine/AbstractService.java	19 Feb 2004 17:38:00 -0000	1.5
>+++ framework/src/org/apache/tapestry/engine/AbstractService.java	15 Oct 2004 12:18:05 -0000
>@@ -85,18 +85,9 @@
>      *
>      **/
> 
>-    protected String[] getServiceContext(RequestContext context)
>+    protected String[] getServiceContext(RequestContext requestContext)
>     {
>-        String service = context.getParameter(Tapestry.SERVICE_QUERY_PARAMETER_NAME);
>-
>-		int slashx = service.indexOf('/');
>-		
>-		if (slashx < 0)
>-			return null;
>-			
>-		String serviceContext = service.substring(slashx + 1);
>-
>-        return new StringSplitter('/').splitToArray(serviceContext);
>+        return requestContext.getParameters(Tapestry.SERVICE_QUERY_PARAMETER_NAME);
>     }
> 
>     /**
>Index: framework/src/org/apache/tapestry/engine/ActionService.java
>===================================================================
>RCS file: /home/cvspublic/jakarta-tapestry/framework/src/org/apache/tapestry/engine/Attic/ActionService.java,v
>retrieving revision 1.9
>diff -u -r1.9 ActionService.java
>--- framework/src/org/apache/tapestry/engine/ActionService.java	19 Feb 2004 17:38:00 -0000	1.9
>+++ framework/src/org/apache/tapestry/engine/ActionService.java	15 Oct 2004 12:18:05 -0000
>@@ -26,7 +26,9 @@
> import org.apache.tapestry.IRequestCycle;
> import org.apache.tapestry.StaleSessionException;
> import org.apache.tapestry.Tapestry;
>+import org.apache.tapestry.request.RequestContext;
> import org.apache.tapestry.request.ResponseOutputStream;
>+import org.apache.tapestry.spec.IApplicationSpecification;
> 
> /**
>  *  A context-sensitive service related to {@link org.apache.tapestry.form.Form} 
>@@ -57,36 +59,55 @@
> 
>     private static final String STATEFUL_OFF = "0";
> 
>-    public ILink getLink(IRequestCycle cycle, IComponent component, Object[] parameters)
>+    /**
>+     * @see org.apache.tapestry.engine.IEngineService#getLink(org.apache.tapestry.IRequestCycle, org.apache.tapestry.IComponent, java.lang.Object[])
>+     */
>+    public ILink getLink(IRequestCycle requestCycle, IComponent component, Object[] parameters)
>     {
>-        if (parameters == null || parameters.length != 1)
>-            throw new IllegalArgumentException(
>-                Tapestry.format("service-single-parameter", Tapestry.ACTION_SERVICE));
>+        if ((parameters == null) || (parameters.length != 1))
>+        {
>+            throw new IllegalArgumentException(Tapestry.format("service-single-parameter", Tapestry.ACTION_SERVICE));
>+        }
> 
>-        String stateful = cycle.getEngine().isStateful() ? STATEFUL_ON : STATEFUL_OFF;
>+        String stateful = requestCycle.getEngine().isStateful() ? STATEFUL_ON : STATEFUL_OFF;
>+        IPage renderPage = requestCycle.getPage();
>         IPage componentPage = component.getPage();
>-        IPage responsePage = cycle.getPage();
> 
>-        boolean complex = (componentPage != responsePage);
>+        boolean complex = (componentPage != renderPage);
> 
>         String[] serviceContext = new String[complex ? 5 : 4];
> 
>         int i = 0;
> 
>+        serviceContext[i++] = Tapestry.ACTION_SERVICE;
>         serviceContext[i++] = stateful;
>-        serviceContext[i++] = responsePage.getPageName();
>         serviceContext[i++] = (String) parameters[0];
> 
>-        // Because of Block/InsertBlock, the component may not be on
>-        // the same page as the response page and we need to make
>-        // allowances for this.
>-
>         if (complex)
>+        {
>             serviceContext[i++] = componentPage.getPageName();
>+        }
> 
>         serviceContext[i++] = component.getIdPath();
> 
>-        return constructLink(cycle, Tapestry.ACTION_SERVICE, serviceContext, null, true);
>+        String suffix = BaseEngine.getPageUrlSuffix(requestCycle.getEngine().getSpecification());
>+        
>+        return new EngineServiceLink(requestCycle, renderPage.getPageName() + suffix, serviceContext, null);
>+    }
>+    
>+    protected String[] getServiceContext(RequestContext requestContext)
>+    {
>+        IApplicationSpecification specification = requestContext.getServlet().getApplicationSpecification();
>+        String urlSuffix = BaseEngine.getPageUrlSuffix(specification);
>+        String[] serviceContext = requestContext.getParameters(Tapestry.SERVICE_QUERY_PARAMETER_NAME);
>+        String servletPath = requestContext.getRequest().getServletPath();
>+
>+        // Remove service name from service context
>+        serviceContext[0] = serviceContext[1];
>+        // Insert page name as second service context element
>+        serviceContext[1] = servletPath.substring(1, servletPath.indexOf(urlSuffix)).replace('/', '.');
>+        
>+        return serviceContext;
>     }
> 
>     public void service(
>Index: framework/src/org/apache/tapestry/engine/BaseEngine.java
>===================================================================
>RCS file: /home/cvspublic/jakarta-tapestry/framework/src/org/apache/tapestry/engine/Attic/BaseEngine.java,v
>retrieving revision 1.6
>diff -u -r1.6 BaseEngine.java
>--- framework/src/org/apache/tapestry/engine/BaseEngine.java	19 Feb 2004 17:38:00 -0000	1.6
>+++ framework/src/org/apache/tapestry/engine/BaseEngine.java	15 Oct 2004 12:18:06 -0000
>@@ -30,6 +30,8 @@
> import org.apache.tapestry.IRequestCycle;
> import org.apache.tapestry.Tapestry;
> import org.apache.tapestry.record.SessionPageRecorder;
>+import org.apache.tapestry.request.RequestContext;
>+import org.apache.tapestry.spec.IApplicationSpecification;
> 
> /**
>  *  Concrete implementation of {@link org.apache.tapestry.IEngine} used for ordinary
>@@ -51,6 +53,68 @@
>     private transient Map _recorders;
> 
>     private transient Set _activePageNames;
>+
>+    public static final String SERVICE_URL_SUFFIX = "org.apache.tapestry.service-url-suffix";
>+    public static final String PAGE_URL_SUFFIX = "org.apache.tapestry.page-url-suffix";
>+    
>+    public static final String DEFAULT_SERVICE_URL_SUFFIX = ".tdo";
>+    public static final String DEFAULT_PAGE_URL_SUFFIX = ".tap";
>+    
>+    public static final String getServiceUrlSuffix(IApplicationSpecification specification) {
>+        String retval = specification.getProperty(SERVICE_URL_SUFFIX);
>+        if (retval == null) {
>+            return DEFAULT_SERVICE_URL_SUFFIX;
>+        } else {
>+            return retval;
>+        }
>+    }
>+    
>+    public static final String getPageUrlSuffix(IApplicationSpecification specification) {
>+        String retval = specification.getProperty(PAGE_URL_SUFFIX);
>+        if (retval == null) {
>+            return DEFAULT_PAGE_URL_SUFFIX;
>+        } else {
>+            return retval;
>+        }
>+    }
>+    
>+    protected String extractServiceName(RequestContext requestContext)
>+    {
>+        String[] serviceContext = requestContext.getParameters(Tapestry.SERVICE_QUERY_PARAMETER_NAME);
>+        
>+        if (requestContext.getRequest().getParameter(Tapestry.TAG_SUPPORT_SERVICE_ATTRIBUTE) != null)
>+        {
>+            return Tapestry.TAGSUPPORT_SERVICE;
>+        }
>+
>+        String servletPath = requestContext.getRequest().getServletPath();
>+        IApplicationSpecification specification = this.getSpecification();
>+        String pageUrlSuffix = getPageUrlSuffix(specification);
>+        
>+        if (servletPath.endsWith(pageUrlSuffix))
>+        {
>+            if ((serviceContext == null) || (serviceContext.length == 0))
>+            {
>+                if (requestContext.getRequest().getParameter(Tapestry.PARAMETERS_QUERY_PARAMETER_NAME) == null)
>+                {
>+                    return Tapestry.PAGE_SERVICE;
>+                }
>+                
>+                return Tapestry.EXTERNAL_SERVICE;
>+            }
>+            
>+            return serviceContext[0];
>+        }
>+        
>+        String serviceUrlSuffix = getServiceUrlSuffix(specification);
>+        
>+        if (servletPath.endsWith(serviceUrlSuffix))
>+        {
>+            return servletPath.substring(1, servletPath.indexOf(serviceUrlSuffix)).replace('/', '.');
>+        }
>+        
>+        throw new ApplicationRuntimeException("Invalid request: " + requestContext.getRequest().getRequestURL());
>+    }
> 
>     /**
>      *  Removes all page recorders that contain no changes, or
>Index: framework/src/org/apache/tapestry/engine/DirectService.java
>===================================================================
>RCS file: /home/cvspublic/jakarta-tapestry/framework/src/org/apache/tapestry/engine/Attic/DirectService.java,v
>retrieving revision 1.9
>diff -u -r1.9 DirectService.java
>--- framework/src/org/apache/tapestry/engine/DirectService.java	19 Feb 2004 17:38:00 -0000	1.9
>+++ framework/src/org/apache/tapestry/engine/DirectService.java	15 Oct 2004 12:18:06 -0000
>@@ -28,6 +28,7 @@
> import org.apache.tapestry.Tapestry;
> import org.apache.tapestry.request.RequestContext;
> import org.apache.tapestry.request.ResponseOutputStream;
>+import org.apache.tapestry.spec.IApplicationSpecification;
> 
> /**
>  *  Implementation of the direct service, which encodes the page and component id in
>@@ -56,39 +57,52 @@
>      **/
> 
>     private static final String STATEFUL_OFF = "0";
>-
>-    public ILink getLink(IRequestCycle cycle, IComponent component, Object[] parameters)
>+    
>+    /**
>+     * @see org.apache.tapestry.engine.IEngineService#getLink(org.apache.tapestry.IRequestCycle, org.apache.tapestry.IComponent, java.lang.Object[])
>+     */
>+    public ILink getLink(IRequestCycle requestCycle, IComponent component, Object[] parameters)
>     {
>-
>-        // New since 1.0.1, we use the component to determine
>-        // the page, not the cycle.  Through the use of tricky
>-        // things such as Block/InsertBlock, it is possible 
>-        // that a component from a page different than
>-        // the response page will render.
>-        // In 1.0.6, we start to record *both* the render page
>-        // and the component page (if different), as the extended
>-        // context.
>-
>-        IPage renderPage = cycle.getPage();
>+        IPage renderPage = requestCycle.getPage();
>         IPage componentPage = component.getPage();
>-
>+        
>         boolean complex = renderPage != componentPage;
>+        
>+        String stateful = requestCycle.getEngine().isStateful() ? STATEFUL_ON : STATEFUL_OFF;
> 
>-        String[] context = complex ? new String[4] : new String[3];
>-
>+        String[] serviceContext = new String[complex ? 4 : 3];
>+        
>         int i = 0;
> 
>-        String stateful = cycle.getEngine().isStateful() ? STATEFUL_ON : STATEFUL_OFF;
>-
>-        context[i++] = stateful;
>-
>+        serviceContext[i++] = Tapestry.DIRECT_SERVICE;
>+        serviceContext[i++] = stateful;
>+        
>         if (complex)
>-            context[i++] = renderPage.getPageName();
>-
>-        context[i++] = componentPage.getPageName();
>-        context[i++] = component.getIdPath();
>-
>-        return constructLink(cycle, Tapestry.DIRECT_SERVICE, context, parameters, true);
>+        {
>+            serviceContext[i++] = componentPage.getPageName();
>+        }
>+        
>+        serviceContext[i++] = component.getIdPath();
>+        
>+        String suffix = BaseEngine.getPageUrlSuffix(requestCycle.getEngine().getSpecification());
>+        
>+        return new EngineServiceLink(requestCycle, renderPage.getPageName() + suffix, serviceContext, parameters);
>+    }
>+    
>+    protected String[] getServiceContext(RequestContext requestContext)
>+    {
>+        IApplicationSpecification specification = requestContext.getServlet().getApplicationSpecification();
>+        String urlSuffix = BaseEngine.getPageUrlSuffix(specification);
>+        String[] serviceContext = requestContext.getParameters(Tapestry.SERVICE_QUERY_PARAMETER_NAME);
>+        
>+        String servletPath = requestContext.getRequest().getServletPath();
>+        
>+        // Remove service name from service context
>+        serviceContext[0] = serviceContext[1];
>+        // Insert page name as second service context element
>+        serviceContext[1] = servletPath.substring(1, servletPath.indexOf(urlSuffix)).replace('/', '.');
>+        
>+        return serviceContext;
>     }
> 
>     public void service(
>Index: framework/src/org/apache/tapestry/engine/EngineServiceLink.java
>===================================================================
>RCS file: /home/cvspublic/jakarta-tapestry/framework/src/org/apache/tapestry/engine/Attic/EngineServiceLink.java,v
>retrieving revision 1.8
>diff -u -r1.8 EngineServiceLink.java
>--- framework/src/org/apache/tapestry/engine/EngineServiceLink.java	19 Feb 2004 17:38:00 -0000	1.8
>+++ framework/src/org/apache/tapestry/engine/EngineServiceLink.java	15 Oct 2004 12:18:07 -0000
>@@ -14,16 +14,17 @@
> 
> package org.apache.tapestry.engine;
> 
>+import java.io.IOException;
> import java.io.UnsupportedEncodingException;
>+import java.net.URLEncoder;
> import java.util.ArrayList;
> import java.util.List;
> 
>-import org.apache.commons.codec.net.URLCodec;
>-import org.apache.commons.lang.builder.ToStringBuilder;
> import org.apache.tapestry.ApplicationRuntimeException;
> import org.apache.tapestry.IRequestCycle;
> import org.apache.tapestry.Tapestry;
> import org.apache.tapestry.request.RequestContext;
>+import org.apache.tapestry.util.io.DataSqueezer;
> 
> /**
>  *  A EngineServiceLink represents a possible action within the client web browser;
>@@ -42,14 +43,38 @@
> 
> public class EngineServiceLink implements ILink
> {
>-    private static final int DEFAULT_HTTP_PORT = 80;
>-    private static final URLCodec _urlCodec = new URLCodec();
> 
>-    private IRequestCycle _cycle;
>-    private String _service;
>+    protected IRequestCycle _cycle;
>+
>+    private String servletPath;
>+
>+    private String[] serviceContext;
>+
>     private String[] _parameters;
>+    
>     private boolean _stateful;
> 
>+    public EngineServiceLink(IRequestCycle requestCycle, String servletPath,
>+            String[] serviceContext, Object[] parameters) {
>+        _cycle = requestCycle;
>+        
>+        int idx = servletPath.lastIndexOf('.');
>+        this.servletPath = servletPath.substring(0, idx).replace('.', '/')
>+                + servletPath.substring(idx);
>+        
>+        this.serviceContext = serviceContext;
>+
>+        if (parameters != null) {
>+            DataSqueezer squeezer = requestCycle.getEngine().getDataSqueezer();
>+
>+            try {
>+                _parameters = squeezer.squeeze(parameters);
>+            } catch (IOException e) {
>+                throw new ApplicationRuntimeException(e);
>+            }
>+        }
>+    }
>+    
>     /**
>      *  Creates a new EngineServiceLink.  A EngineServiceLink always names a service to be activated
>      *  by the link, has an optional list of service context strings,
>@@ -84,167 +109,128 @@
>         boolean stateful)
>     {
>         _cycle = cycle;
>-        _service = constructServiceValue(serviceName, serviceContext);
>+        servletPath = serviceName.replace('.','/') + BaseEngine.getServiceUrlSuffix(cycle.getEngine().getSpecification());
>+        this.serviceContext = serviceContext;
>         _parameters = serviceParameters;
>         _stateful = stateful;
>     }
> 
>-    private String constructServiceValue(String serviceName, String[] serviceContext)
>-    {
>-        int count = Tapestry.size(serviceContext);
>-
>-        if (count == 0)
>-            return serviceName;
>-
>-        StringBuffer buffer = new StringBuffer(serviceName);
>-
>-        for (int i = 0; i < count; i++)
>-        {
>-            buffer.append('/');
>-
>-            buffer.append(serviceContext[i]);
>-        }
>-
>-        return buffer.toString();
>-    }
>-
>-    public String getURL()
>-    {
>+    /**
>+     * @see org.apache.tapestry.engine.ILink#getURL()
>+     */
>+    public String getURL() {
>         return getURL(null, true);
>     }
> 
>-    public String getURL(String anchor, boolean includeParameters)
>-    {
>+    /**
>+     * @see org.apache.tapestry.engine.ILink#getURL(java.lang.String, boolean)
>+     */
>+    public String getURL(String anchor, boolean includeParameters) {
>         return constructURL(new StringBuffer(), anchor, includeParameters);
>     }
> 
>-    public String getAbsoluteURL()
>-    {
>+    /**
>+     * @see org.apache.tapestry.engine.ILink#getAbsoluteURL()
>+     */
>+    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();
>+    /**
>+     * @see org.apache.tapestry.engine.ILink#getAbsoluteURL(java.lang.String,
>+     *      java.lang.String, int, java.lang.String, boolean)
>+     */
>+    public String getAbsoluteURL(String scheme, String server, int port,
>+            String anchor, boolean includeParameters) {
>         RequestContext context = _cycle.getRequestContext();
>+        StringBuffer buffer = new StringBuffer();
> 
>-        if (scheme == null)
>-            scheme = context.getScheme();
>-
>-        buffer.append(scheme);
>+        buffer.append((scheme != null) ? scheme : context.getScheme());
>         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.
>+        buffer.append((server != null) ? server : context.getServerName());
>+        buffer.append(':');
>+        buffer.append((port != 0) ? port : context.getServerPort());
> 
>         return constructURL(buffer, anchor, includeParameters);
>     }
> 
>-    private String constructURL(StringBuffer buffer, String anchor, boolean includeParameters)
>-    {
>-        buffer.append(_cycle.getEngine().getServletPath());
>+    private String constructURL(StringBuffer buffer, String anchor,
>+            boolean includeParameters) {
>+        RequestContext context = _cycle.getRequestContext();
>+        
>+        buffer.append(context.getRequest().getContextPath()).append('/')
>+                .append(servletPath);
>+
>+        if (includeParameters) {
>+            String encoding = _cycle.getEngine().getOutputEncoding();
> 
>-        if (includeParameters)
>-        {
>             buffer.append('?');
>-            buffer.append(Tapestry.SERVICE_QUERY_PARAMETER_NAME);
>-            buffer.append('=');
>-            buffer.append(_service);
>-
>-            int count = Tapestry.size(_parameters);
>-
>-            for (int i = 0; i < count; i++)
>-            {
>-                buffer.append('&');
>-
>-                buffer.append(Tapestry.PARAMETERS_QUERY_PARAMETER_NAME);
>-                buffer.append('=');
>-
>-                String encoding = _cycle.getEngine().getOutputEncoding();
>-                try
>-                {
>-                    String encoded = _urlCodec.encode(_parameters[i], encoding);
>-                    buffer.append(encoded);
>+
>+            try {
>+                if (serviceContext != null) {
>+                    for (int i = 0; i < serviceContext.length; i++) {
>+                        buffer.append(Tapestry.SERVICE_QUERY_PARAMETER_NAME);
>+                        buffer.append('=');
>+                        buffer.append(URLEncoder.encode(this.serviceContext[i],
>+                                encoding));
>+                        buffer.append('&');
>+                    }
>                 }
>-                catch (UnsupportedEncodingException e)
>-                {
>-                    throw new ApplicationRuntimeException(
>-                        Tapestry.format("illegal-encoding", encoding),
>-                        e);
>+
>+                if (_parameters != null) {
>+                    for (int i = 0; i < _parameters.length; i++) {
>+                        buffer.append(Tapestry.PARAMETERS_QUERY_PARAMETER_NAME);
>+                        buffer.append('=');
>+                        buffer.append(URLEncoder.encode(_parameters[i],
>+                                encoding));
>+                        buffer.append('&');
>+                    }
>                 }
>+
>+                // Delete trailing & or ?
>+                buffer.deleteCharAt(buffer.length() - 1);
>+            } catch (UnsupportedEncodingException e) {
>+                throw new ApplicationRuntimeException(e);
>             }
>         }
> 
>-        if (anchor != null)
>-        {
>-            buffer.append('#');
>-            buffer.append(anchor);
>+        if (anchor != null) {
>+            buffer.append('#').append(anchor);
>         }
> 
>-        String result = buffer.toString();
>-
>         if (_stateful)
>-            result = _cycle.encodeURL(result);
>-
>-        return result;
>+            return _cycle.encodeURL(buffer.toString());
>+        else
>+            return buffer.toString();
>     }
> 
>-    public String[] getParameterNames()
>-    {
>-        List list = new ArrayList();
>-
>-        list.add(Tapestry.SERVICE_QUERY_PARAMETER_NAME);
>-
>-        if (Tapestry.size(_parameters) != 0)
>-            list.add(Tapestry.PARAMETERS_QUERY_PARAMETER_NAME);
>-
>-        return (String[]) list.toArray(new String[list.size()]);
>-    }
>+    /**
>+     * @see org.apache.tapestry.engine.ILink#getParameterNames()
>+     */
>+    public String[] getParameterNames() {
>+        List parameterList = new ArrayList(2);
> 
>-    public String[] getParameterValues(String name)
>-    {
>-        if (name.equals(Tapestry.SERVICE_QUERY_PARAMETER_NAME))
>-        {
>-            return new String[] { _service };
>+        if ((this.serviceContext != null) && (this.serviceContext.length > 0)) {
>+            parameterList.add(Tapestry.SERVICE_QUERY_PARAMETER_NAME);
>         }
> 
>-        if (name.equals(Tapestry.PARAMETERS_QUERY_PARAMETER_NAME))
>-        {
>-            return _parameters;
>+        if ((_parameters != null) && (_parameters.length > 0)) {
>+            parameterList.add(Tapestry.PARAMETERS_QUERY_PARAMETER_NAME);
>         }
> 
>-        throw new IllegalArgumentException(
>-            Tapestry.format("EngineServiceLink.unknown-parameter-name", name));
>+        return (String[]) parameterList
>+                .toArray(new String[parameterList.size()]);
>     }
> 
>-    public String toString()
>-    {
>-        ToStringBuilder builder = new ToStringBuilder(this);
>+    /**
>+     * @see org.apache.tapestry.engine.ILink#getParameterValues(java.lang.String)
>+     */
>+    public String[] getParameterValues(String name) {
>+        if (name.equals(Tapestry.PARAMETERS_QUERY_PARAMETER_NAME)) { return _parameters; }
> 
>-        builder.append("service", _service);
>-        builder.append("parameters", _parameters);
>-        builder.append("stateful", _stateful);
>+        if (name.equals(Tapestry.SERVICE_QUERY_PARAMETER_NAME)) { return this.serviceContext; }
> 
>-        return builder.toString();
>+        throw new IllegalArgumentException(Tapestry.format(
>+                "EngineServiceLink.unknown-parameter-name", name));
>     }
>-
> }
>Index: framework/src/org/apache/tapestry/engine/ExternalService.java
>===================================================================
>RCS file: /home/cvspublic/jakarta-tapestry/framework/src/org/apache/tapestry/engine/Attic/ExternalService.java,v
>retrieving revision 1.9
>diff -u -r1.9 ExternalService.java
>--- framework/src/org/apache/tapestry/engine/ExternalService.java	19 Feb 2004 17:38:00 -0000	1.9
>+++ framework/src/org/apache/tapestry/engine/ExternalService.java	15 Oct 2004 12:18:07 -0000
>@@ -23,7 +23,9 @@
> import org.apache.tapestry.IExternalPage;
> import org.apache.tapestry.IRequestCycle;
> import org.apache.tapestry.Tapestry;
>+import org.apache.tapestry.request.RequestContext;
> import org.apache.tapestry.request.ResponseOutputStream;
>+import org.apache.tapestry.spec.IApplicationSpecification;
> 
> /**
>  * The external service enables external applications
>@@ -109,21 +111,38 @@
> 
> public class ExternalService extends AbstractService
> {
>-
>-    public ILink getLink(IRequestCycle cycle, IComponent component, Object[] parameters)
>+    /**
>+     * @see org.apache.tapestry.engine.IEngineService#getLink(org.apache.tapestry.IRequestCycle, org.apache.tapestry.IComponent, java.lang.Object[])
>+     */
>+    public ILink getLink(IRequestCycle requestCycle, IComponent component, Object[] parameters)
>     {
>         if (parameters == null || parameters.length == 0)
>-            throw new ApplicationRuntimeException(
>-                Tapestry.format("service-requires-parameters", Tapestry.EXTERNAL_SERVICE));
>+        {
>+            throw new ApplicationRuntimeException(Tapestry.format("service-requires-parameters", Tapestry.EXTERNAL_SERVICE));
>+        }
> 
>-        String pageName = (String) parameters[0];
>-        String[] context = new String[] { pageName };
>+        String page = (String) parameters[0];
> 
>         Object[] pageParameters = new Object[parameters.length - 1];
>         System.arraycopy(parameters, 1, pageParameters, 0, parameters.length - 1);
> 
>-        return constructLink(cycle, Tapestry.EXTERNAL_SERVICE, context, pageParameters, true);
>+        String suffix = BaseEngine.getPageUrlSuffix(requestCycle.getEngine().getSpecification());
>+        
>+        return new EngineServiceLink(requestCycle, page + suffix, null, pageParameters);
>     }
>+    
>+    /**
>+     * @see org.apache.tapestry.engine.AbstractService#getServiceContext(org.apache.tapestry.request.RequestContext)
>+     */
>+    protected String[] getServiceContext(RequestContext requestContext)
>+    {
>+        IApplicationSpecification specification = requestContext.getServlet().getApplicationSpecification();
>+        String urlSuffix = BaseEngine.getPageUrlSuffix(specification);
>+        String servletPath = requestContext.getRequest().getServletPath();
>+
>+        return new String[] { servletPath.substring(1, servletPath.indexOf(urlSuffix)).replace('/', '.') };
>+    }
>+
> 
>     public void service(
>         IEngineServiceView engine,
>Index: framework/src/org/apache/tapestry/engine/HomeService.java
>===================================================================
>RCS file: /home/cvspublic/jakarta-tapestry/framework/src/org/apache/tapestry/engine/Attic/HomeService.java,v
>retrieving revision 1.7
>diff -u -r1.7 HomeService.java
>--- framework/src/org/apache/tapestry/engine/HomeService.java	19 Feb 2004 17:38:00 -0000	1.7
>+++ framework/src/org/apache/tapestry/engine/HomeService.java	15 Oct 2004 12:18:07 -0000
>@@ -41,13 +41,11 @@
> public class HomeService extends AbstractService
> {
> 
>-    public ILink getLink(IRequestCycle cycle, IComponent component, Object[] parameters)
>+    public ILink getLink(IRequestCycle requestCycle, IComponent component, Object[] parameters)
>     {
>-        if (Tapestry.size(parameters) != 0)
>-            throw new IllegalArgumentException(
>-                Tapestry.format("service-no-parameters", Tapestry.HOME_SERVICE));
>-
>-        return constructLink(cycle, Tapestry.HOME_SERVICE, null, null, true);
>+        String suffix = BaseEngine.getServiceUrlSuffix(requestCycle.getEngine().getSpecification());
>+        
>+        return new EngineServiceLink(requestCycle, Tapestry.HOME_SERVICE + suffix, null, null);
>     }
> 
>     public void service(
>Index: framework/src/org/apache/tapestry/engine/PageService.java
>===================================================================
>RCS file: /home/cvspublic/jakarta-tapestry/framework/src/org/apache/tapestry/engine/Attic/PageService.java,v
>retrieving revision 1.8
>diff -u -r1.8 PageService.java
>--- framework/src/org/apache/tapestry/engine/PageService.java	19 Feb 2004 17:38:00 -0000	1.8
>+++ framework/src/org/apache/tapestry/engine/PageService.java	15 Oct 2004 12:18:08 -0000
>@@ -25,6 +25,7 @@
> import org.apache.tapestry.Tapestry;
> import org.apache.tapestry.request.RequestContext;
> import org.apache.tapestry.request.ResponseOutputStream;
>+import org.apache.tapestry.spec.IApplicationSpecification;
> 
> /**
>  *  Basic server for creating a link to another page in the application.
>@@ -37,15 +38,33 @@
> 
> public class PageService extends AbstractService
> {
>-
>-    public ILink getLink(IRequestCycle cycle, IComponent component, Object[] parameters)
>+    /**
>+     * @see org.apache.tapestry.engine.IEngineService#getLink(org.apache.tapestry.IRequestCycle, org.apache.tapestry.IComponent, java.lang.Object[])
>+     */
>+    public ILink getLink(IRequestCycle requestCycle, IComponent component, Object[] parameters)
>     {
>         if (Tapestry.size(parameters) != 1)
>-            throw new IllegalArgumentException(
>-                Tapestry.format("service-single-parameter", Tapestry.PAGE_SERVICE));
>+        {
>+            throw new IllegalArgumentException(Tapestry.format("service-single-parameter", Tapestry.PAGE_SERVICE));
>+        }
> 
>-        return constructLink(cycle, Tapestry.PAGE_SERVICE, new String[] {(String) parameters[0]}, null, true);
>+        String page = (String) parameters[0];
>+        
>+        String suffix = BaseEngine.getPageUrlSuffix(requestCycle.getEngine().getSpecification());
>+        
>+        return new EngineServiceLink(requestCycle, page + suffix, null, null);
>+    }
>+    
>+    /**
>+     * @see org.apache.tapestry.engine.AbstractService#getServiceContext(org.apache.tapestry.request.RequestContext)
>+     */
>+    protected String[] getServiceContext(RequestContext requestContext)
>+    {
>+        IApplicationSpecification specification = requestContext.getServlet().getApplicationSpecification();
>+        String urlSuffix = BaseEngine.getPageUrlSuffix(specification);
>+        String servletPath = requestContext.getRequest().getServletPath();
> 
>+        return new String[] { servletPath.substring(1, servletPath.indexOf(urlSuffix)).replace('/', '.') };
>     }
> 
>     public void service(
>Index: framework/src/org/apache/tapestry/engine/ResetService.java
>===================================================================
>RCS file: /home/cvspublic/jakarta-tapestry/framework/src/org/apache/tapestry/engine/Attic/ResetService.java,v
>retrieving revision 1.7
>diff -u -r1.7 ResetService.java
>--- framework/src/org/apache/tapestry/engine/ResetService.java	19 Feb 2004 17:38:00 -0000	1.7
>+++ framework/src/org/apache/tapestry/engine/ResetService.java	15 Oct 2004 12:18:08 -0000
>@@ -42,16 +42,11 @@
> public class ResetService extends AbstractService
> {
> 
>-    public ILink getLink(IRequestCycle cycle, IComponent component, Object[] parameters)
>+    public ILink getLink(IRequestCycle requestCycle, IComponent component, Object[] parameters)
>     {
>-        if (Tapestry.size(parameters) != 0)
>-            throw new IllegalArgumentException(
>-                Tapestry.format("service-no-parameters", Tapestry.RESET_SERVICE));
>-
>-        String[] context = new String[1];
>-        context[0] = component.getPage().getPageName();
>-
>-        return constructLink(cycle, Tapestry.RESET_SERVICE, context, null, true);
>+        String suffix = BaseEngine.getServiceUrlSuffix(requestCycle.getEngine().getSpecification());
>+        
>+        return new EngineServiceLink(requestCycle, Tapestry.RESET_SERVICE + suffix, null, null);
>     }
> 
>     public String getName()
>Index: framework/src/org/apache/tapestry/engine/RestartService.java
>===================================================================
>RCS file: /home/cvspublic/jakarta-tapestry/framework/src/org/apache/tapestry/engine/Attic/RestartService.java,v
>retrieving revision 1.6
>diff -u -r1.6 RestartService.java
>--- framework/src/org/apache/tapestry/engine/RestartService.java	19 Feb 2004 17:38:00 -0000	1.6
>+++ framework/src/org/apache/tapestry/engine/RestartService.java	15 Oct 2004 12:18:08 -0000
>@@ -37,13 +37,11 @@
> public class RestartService extends AbstractService
> {
> 
>-    public ILink getLink(IRequestCycle cycle, IComponent component, Object[] parameters)
>+    public ILink getLink(IRequestCycle requestCycle, IComponent component, Object[] parameters)
>     {
>-        if (Tapestry.size(parameters) != 0)
>-            throw new IllegalArgumentException(
>-                Tapestry.format("service-no-parameters", Tapestry.RESTART_SERVICE));
>-
>-        return constructLink(cycle, Tapestry.RESTART_SERVICE, null, null, true);
>+        String suffix = BaseEngine.getServiceUrlSuffix(requestCycle.getEngine().getSpecification());
>+        
>+        return new EngineServiceLink(requestCycle, Tapestry.RESTART_SERVICE + suffix, null, null);
>     }
> 
>     public void service(
>Index: framework/src/org/apache/tapestry/parse/SpecificationParser.java
>===================================================================
>RCS file: /home/cvspublic/jakarta-tapestry/framework/src/org/apache/tapestry/parse/Attic/SpecificationParser.java,v
>retrieving revision 1.19
>diff -u -r1.19 SpecificationParser.java
>--- framework/src/org/apache/tapestry/parse/SpecificationParser.java	19 Feb 2004 17:37:41 -0000	1.19
>+++ framework/src/org/apache/tapestry/parse/SpecificationParser.java	15 Oct 2004 12:18:11 -0000
>@@ -101,7 +101,17 @@
>      **/
> 
>     public static final String EXTENDED_PROPERTY_NAME_PATTERN = "^_?[a-zA-Z](\\w|-|\\.)*$";
>-
>+    
>+    /**
>+     *  Like extended property name, but allows forward slashes in the name as
>+     *  well.
>+     * 
>+     *  @since 2.2
>+     * 
>+     **/
>+    
>+    public static final String PATH_PROPERTY_NAME_PATTERN = "^_?[a-zA-Z](\\w|-|\\.|/)*$";
>+    
>     /**
>      *  Perl5 pattern that parameter names must conform to.  
>      *  Letter, followed by letter, number or underscore.
>@@ -132,7 +142,7 @@
>      * 
>      **/
> 
>-    public static final String PAGE_NAME_PATTERN = EXTENDED_PROPERTY_NAME_PATTERN;
>+    public static final String PAGE_NAME_PATTERN = PATH_PROPERTY_NAME_PATTERN;
> 
>     /**
>      *  Perl5 pattern for component alias. 
>@@ -186,7 +196,7 @@
>      * 
>      **/
> 
>-    public static final String SERVICE_NAME_PATTERN = EXTENDED_PROPERTY_NAME_PATTERN;
>+    public static final String SERVICE_NAME_PATTERN = PATH_PROPERTY_NAME_PATTERN;
> 
>     /**
>      *  Perl5 pattern for library ids.  Letter followed
>
>
>
>__________ NOD32 1.895 (20041014) Information __________
>
>This message was checked by NOD32 antivirus system.
>http://www.nod32.com
>
>  
>
>------------------------------------------------------------------------
>
>---------------------------------------------------------------------
>To unsubscribe, e-mail: tapestry-dev-unsubscribe@jakarta.apache.org
>For additional commands, e-mail: tapestry-dev-help@jakarta.apache.org
>
>__________ NOD32 1.895 (20041014) Information __________
>
>This message was checked by NOD32 antivirus system.
>http://www.nod32.com
>
>  
>


Re: friendly urls?

Posted by Mikaël Cluseau <nw...@nwrk.dyndns.org>.
I forgot to mention that you will have to map "*.tap" and "*.tdo" to 
your ApplicationServlet (if you don't overide the default suffixes).

Here is another patch which changes "." to "/" in page names, so that 
you don't break the default Tapestry naming conventions but can simulate 
folders.

Mikael.

Re: friendly urls?

Posted by Mikaël Cluseau <nw...@nwrk.dyndns.org>.
Erik Hatcher wrote:

> Warner - Paul's patch is available on the Tapestry wiki.  You're  
> welcome to apply it locally and give it a shot.

I did it against the latest CVS version (branch-3-0), and fixed a bug by 
overiding EngineServiceLink instead of creating a new ILink 
implementation. Works well on my app, which uses custom services, forms, 
direct, external and action links (and also threads for long actions or 
complex searches ;-) ).

I've attached my patch.

Re: friendly urls?

Posted by Erik Hatcher <er...@ehatchersolutions.com>.
Warner - Paul's patch is available on the Tapestry wiki.  You're  
welcome to apply it locally and give it a shot.

	Erik

On Oct 7, 2004, at 5:14 PM, Howard Lewis Ship wrote:

> Paul Ferraro.  He was voted in because he had a deep understanding of
> Tapestry, and a willingness to help out.
>
> I've been getting in the way, with the HiveMind changes. Because they
> are so disruptive, I have been encouraging others to stay away while I
> hammer out the changes. I think that  stage should be coming to a
> close, soon.
>
>
> On Thu, 7 Oct 2004 14:12:23 -0700, Warner Onstine
> <sw...@warneronstine.com> wrote:
>> I thought that he was brought on to apply his patch so that we would
>> have it before 3.1 (sorry I forgot his name).
>>
>> -warner
>>
>>
>>
>> On Oct 7, 2004, at 2:09 PM, Howard Lewis Ship wrote:
>>
>>> Still refactoring Tapestry 3.1.  It's an iterative process. So far  
>>> has
>>> been all the "easy" stuff; new functionality is only now beginning to
>>> slip into place.
>>>
>>>
>>> On Thu, 7 Oct 2004 13:37:24 -0700, Warner Onstine
>>> <sw...@warneronstine.com> wrote:
>>>> What happened with incorporating the friendly urls patch? I haven't
>>>> seen anything wizz by on the commits.
>>>>
>>>> -warner
>>>>
>>>> -------------------------------------------------------------------- 
>>>> -
>>>> To unsubscribe, e-mail: tapestry-dev-unsubscribe@jakarta.apache.org
>>>> For additional commands, e-mail:  
>>>> tapestry-dev-help@jakarta.apache.org
>>>>
>>>>
>>>
>>>
>>> --
>>> Howard M. Lewis Ship
>>> Independent J2EE / Open-Source Java Consultant
>>> Creator, Jakarta Tapestry
>>> Creator, Jakarta HiveMind
>>> http://howardlewisship.com
>>>
>>> ---------------------------------------------------------------------
>>> To unsubscribe, e-mail: tapestry-dev-unsubscribe@jakarta.apache.org
>>> For additional commands, e-mail: tapestry-dev-help@jakarta.apache.org
>>>
>>>
>>
>>
>> ---------------------------------------------------------------------
>>
>>
>> To unsubscribe, e-mail: tapestry-dev-unsubscribe@jakarta.apache.org
>> For additional commands, e-mail: tapestry-dev-help@jakarta.apache.org
>>
>>
>
>
> -- 
> Howard M. Lewis Ship
> Independent J2EE / Open-Source Java Consultant
> Creator, Jakarta Tapestry
> Creator, Jakarta HiveMind
> http://howardlewisship.com
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: tapestry-dev-unsubscribe@jakarta.apache.org
> For additional commands, e-mail: tapestry-dev-help@jakarta.apache.org


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


Re: friendly urls?

Posted by Howard Lewis Ship <hl...@gmail.com>.
Paul Ferraro.  He was voted in because he had a deep understanding of
Tapestry, and a willingness to help out.

I've been getting in the way, with the HiveMind changes. Because they
are so disruptive, I have been encouraging others to stay away while I
hammer out the changes. I think that  stage should be coming to a
close, soon.


On Thu, 7 Oct 2004 14:12:23 -0700, Warner Onstine
<sw...@warneronstine.com> wrote:
> I thought that he was brought on to apply his patch so that we would
> have it before 3.1 (sorry I forgot his name).
> 
> -warner
> 
> 
> 
> On Oct 7, 2004, at 2:09 PM, Howard Lewis Ship wrote:
> 
> > Still refactoring Tapestry 3.1.  It's an iterative process. So far has
> > been all the "easy" stuff; new functionality is only now beginning to
> > slip into place.
> >
> >
> > On Thu, 7 Oct 2004 13:37:24 -0700, Warner Onstine
> > <sw...@warneronstine.com> wrote:
> >> What happened with incorporating the friendly urls patch? I haven't
> >> seen anything wizz by on the commits.
> >>
> >> -warner
> >>
> >> ---------------------------------------------------------------------
> >> To unsubscribe, e-mail: tapestry-dev-unsubscribe@jakarta.apache.org
> >> For additional commands, e-mail: tapestry-dev-help@jakarta.apache.org
> >>
> >>
> >
> >
> > --
> > Howard M. Lewis Ship
> > Independent J2EE / Open-Source Java Consultant
> > Creator, Jakarta Tapestry
> > Creator, Jakarta HiveMind
> > http://howardlewisship.com
> >
> > ---------------------------------------------------------------------
> > To unsubscribe, e-mail: tapestry-dev-unsubscribe@jakarta.apache.org
> > For additional commands, e-mail: tapestry-dev-help@jakarta.apache.org
> >
> >
> 
> 
> ---------------------------------------------------------------------
> 
> 
> To unsubscribe, e-mail: tapestry-dev-unsubscribe@jakarta.apache.org
> For additional commands, e-mail: tapestry-dev-help@jakarta.apache.org
> 
> 


-- 
Howard M. Lewis Ship
Independent J2EE / Open-Source Java Consultant
Creator, Jakarta Tapestry
Creator, Jakarta HiveMind
http://howardlewisship.com

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


Re: friendly urls?

Posted by Warner Onstine <sw...@warneronstine.com>.
I thought that he was brought on to apply his patch so that we would 
have it before 3.1 (sorry I forgot his name).

-warner

On Oct 7, 2004, at 2:09 PM, Howard Lewis Ship wrote:

> Still refactoring Tapestry 3.1.  It's an iterative process. So far has
> been all the "easy" stuff; new functionality is only now beginning to
> slip into place.
>
>
> On Thu, 7 Oct 2004 13:37:24 -0700, Warner Onstine
> <sw...@warneronstine.com> wrote:
>> What happened with incorporating the friendly urls patch? I haven't
>> seen anything wizz by on the commits.
>>
>> -warner
>>
>> ---------------------------------------------------------------------
>> To unsubscribe, e-mail: tapestry-dev-unsubscribe@jakarta.apache.org
>> For additional commands, e-mail: tapestry-dev-help@jakarta.apache.org
>>
>>
>
>
> -- 
> Howard M. Lewis Ship
> Independent J2EE / Open-Source Java Consultant
> Creator, Jakarta Tapestry
> Creator, Jakarta HiveMind
> http://howardlewisship.com
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: tapestry-dev-unsubscribe@jakarta.apache.org
> For additional commands, e-mail: tapestry-dev-help@jakarta.apache.org
>
>


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


Re: friendly urls?

Posted by Howard Lewis Ship <hl...@gmail.com>.
Still refactoring Tapestry 3.1.  It's an iterative process. So far has
been all the "easy" stuff; new functionality is only now beginning to
slip into place.


On Thu, 7 Oct 2004 13:37:24 -0700, Warner Onstine
<sw...@warneronstine.com> wrote:
> What happened with incorporating the friendly urls patch? I haven't
> seen anything wizz by on the commits.
> 
> -warner
> 
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: tapestry-dev-unsubscribe@jakarta.apache.org
> For additional commands, e-mail: tapestry-dev-help@jakarta.apache.org
> 
> 


-- 
Howard M. Lewis Ship
Independent J2EE / Open-Source Java Consultant
Creator, Jakarta Tapestry
Creator, Jakarta HiveMind
http://howardlewisship.com

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