Author: gk
Date: Fri Feb 26 14:30:39 2021
New Revision: 1886953

URL: http://svn.apache.org/viewvc?rev=1886953&view=rev
Log:
TurbineURLMapperService:
- add url mapper to tests and update tests
- fix in method mapToURL: Update provided URI only after entriesKey/key match 
in TurbineURLMapperService
- remove trailing slash in mapped URLs
- update site for url simplifier / mapper
- TODO move packages

Modified:
    turbine/core/trunk/conf/test/CompleteTurbineResources.properties
    turbine/core/trunk/conf/test/TorqueTest.properties
    turbine/core/trunk/conf/turbine-classic-pipeline.xml
    turbine/core/trunk/conf/turbine-url-mapping.json
    
turbine/core/trunk/src/java/org/apache/turbine/modules/actions/sessionvalidator/TemplateSessionValidator.java
    
turbine/core/trunk/src/java/org/apache/turbine/services/urlmapper/TurbineURLMapperService.java
    turbine/core/trunk/src/site/site.xml
    
turbine/core/trunk/src/test/org/apache/turbine/pipeline/DefaultLoginValveTest.java
    
turbine/core/trunk/src/test/org/apache/turbine/services/urlmapper/TurbineURLMapperJSONServiceTest.java
    turbine/core/trunk/xdocs/howto/index.xml
    turbine/core/trunk/xdocs/howto/migrate-from-4_0-howto.xml
    turbine/core/trunk/xdocs/howto/services-howto.xml
    turbine/core/trunk/xdocs/howto/url-mapper-howto.xml

Modified: turbine/core/trunk/conf/test/CompleteTurbineResources.properties
URL: 
http://svn.apache.org/viewvc/turbine/core/trunk/conf/test/CompleteTurbineResources.properties?rev=1886953&r1=1886952&r2=1886953&view=diff
==============================================================================
--- turbine/core/trunk/conf/test/CompleteTurbineResources.properties (original)
+++ turbine/core/trunk/conf/test/CompleteTurbineResources.properties Fri Feb 26 
14:30:39 2021
@@ -643,15 +643,14 @@ services.SessionService.earlyInit=true
 #
 #  U R L M A P P E R   S E R V I C E
 #
-# to use it uncomment 
-# - the valve org.apache.turbine.services.urlmapper.URLMapperValve into 
classic-pipelline.xml
-# - service, pull tool and read configuration  
+# - the valve org.apache.turbine.services.urlmapper.URLMapperValve is 
activated in classic-pipeline.xml
+# - service, optional pull tool and read configuration  
 # - configure turbine-url-mapping in xml, json or yaml
 # -------------------------------------------------------------------
 
-#services.URLMapperService.classname=org.apache.turbine.services.urlmapper.TurbineURLMapperService
+services.URLMapperService.classname=org.apache.turbine.services.urlmapper.TurbineURLMapperService
 
 # new mapper in pull tooll data service
 #tool.request.mlink=org.apache.turbine.services.urlmapper.MappedTemplateLink
 
-#services.URLMapperService.configFile = conf/turbine-url-mapping.xml
+services.URLMapperService.configFile = conf/turbine-url-mapping.xml

Modified: turbine/core/trunk/conf/test/TorqueTest.properties
URL: 
http://svn.apache.org/viewvc/turbine/core/trunk/conf/test/TorqueTest.properties?rev=1886953&r1=1886952&r2=1886953&view=diff
==============================================================================
--- turbine/core/trunk/conf/test/TorqueTest.properties (original)
+++ turbine/core/trunk/conf/test/TorqueTest.properties Fri Feb 26 14:30:39 2021
@@ -35,6 +35,6 @@ torque.dsfactory.default.factory= org.ap
 torque.dsfactory.default.pool.defaultTestOnBorrow=true
 torque.dsfactory.default.pool.validationQuery=SELECT 1 from 
INFORMATION_SCHEMA.SYSTEM_USERS
 torque.dsfactory.default.connection.driver = org.hsqldb.jdbcDriver
-torque.dsfactory.default.connection.url = jdbc:hsqldb:.
+torque.dsfactory.default.connection.url = jdbc:hsqldb:mem:
 torque.dsfactory.default.connection.user = sa
 torque.dsfactory.default.connection.password =

Modified: turbine/core/trunk/conf/turbine-classic-pipeline.xml
URL: 
http://svn.apache.org/viewvc/turbine/core/trunk/conf/turbine-classic-pipeline.xml?rev=1886953&r1=1886952&r2=1886953&view=diff
==============================================================================
--- turbine/core/trunk/conf/turbine-classic-pipeline.xml (original)
+++ turbine/core/trunk/conf/turbine-classic-pipeline.xml Fri Feb 26 14:30:39 
2021
@@ -19,7 +19,6 @@
 -->
 <pipeline name="default">
   <valves>
-    <!--valve>org.apache.turbine.services.urlmapper.URLMapperValve</valve-->
     <valve>org.apache.turbine.pipeline.DefaultSetEncodingValve</valve>
     <valve>org.apache.turbine.pipeline.DetermineActionValve</valve>
     <valve>org.apache.turbine.pipeline.DetermineTargetValve</valve>
@@ -27,6 +26,7 @@
     <valve>org.apache.turbine.pipeline.DefaultLoginValve</valve>
     <valve>org.apache.turbine.pipeline.DefaultSessionValidationValve</valve>
     <valve>org.apache.turbine.pipeline.DefaultACLCreationValve</valve>
+    <valve>org.apache.turbine.services.urlmapper.URLMapperValve</valve>
     <valve>org.apache.turbine.pipeline.ExecutePageValve</valve>
     <valve>org.apache.turbine.pipeline.CleanUpValve</valve>
     <valve>org.apache.turbine.pipeline.DetermineRedirectRequestedValve</valve>

Modified: turbine/core/trunk/conf/turbine-url-mapping.json
URL: 
http://svn.apache.org/viewvc/turbine/core/trunk/conf/turbine-url-mapping.json?rev=1886953&r1=1886952&r2=1886953&view=diff
==============================================================================
--- turbine/core/trunk/conf/turbine-url-mapping.json (original)
+++ turbine/core/trunk/conf/turbine-url-mapping.json Fri Feb 26 14:30:39 2021
@@ -2,7 +2,7 @@
        "name": "default",
        "maps": [
                {
-                       "pattern": 
"/(?<webAppRoot>[\\w]+)/(?<contextPath>\\w+)/register",
+                       "pattern": 
"/(?<webAppRoot>[.\\-\\w]+)/(?<contextPath>\\w+)/register",
                        "implicit-parameters": {
                                "page": "Register",
                                "role": "anon"
@@ -29,12 +29,32 @@
             }
         },
                {
-            "pattern": 
"/(?<webAppRoot>[\\w]+)/(?<contextPath>\\w+)/(?<language>\\w+)/contact",
+            "pattern": 
"/(?<webAppRoot>[\\w]+)/(?<contextPath>\\w+)/contact/(?<kind>\\d)/(?<language>\\w+)",
             "implicit-parameters": {
                 "page": "Contact",
                 "role": "anon"
             },
             "override-parameters": {
+                "role": "anon"
+            }
+        },
+         {
+            "pattern": "/(?<webAppRoot>[\\w]+)/(?<contextPath>\\w+)/info",
+            "implicit-parameters": {
+                "page": "Info",
+                "role": "anon"
+            },
+            "override-parameters": {
+                "role": "anon"
+            }
+        },
+        {
+            "pattern": 
"/(?<webAppRoot>[\\w]+)/(?<contextPath>\\w+)/info/(?<kind>\\d)/(?<language>\\w+)",
+            "implicit-parameters": {
+                "page": "Info",
+                "role": "anon"
+            },
+            "override-parameters": {
                 "role": "anon"
             },
             "ignore-parameters": {

Modified: 
turbine/core/trunk/src/java/org/apache/turbine/modules/actions/sessionvalidator/TemplateSessionValidator.java
URL: 
http://svn.apache.org/viewvc/turbine/core/trunk/src/java/org/apache/turbine/modules/actions/sessionvalidator/TemplateSessionValidator.java?rev=1886953&r1=1886952&r2=1886953&view=diff
==============================================================================
--- 
turbine/core/trunk/src/java/org/apache/turbine/modules/actions/sessionvalidator/TemplateSessionValidator.java
 (original)
+++ 
turbine/core/trunk/src/java/org/apache/turbine/modules/actions/sessionvalidator/TemplateSessionValidator.java
 Fri Feb 26 14:30:39 2021
@@ -36,9 +36,6 @@ import org.apache.turbine.util.RunData;
  * <p>The Template Service requires a different Session Validator
  * because of the way it handles screens.
  *
- * <p>Note that you will need to set the template.login property to the
- * login template.
- *
  * @see TemplateSecureSessionValidator
  * @author <a href="mailto:[email protected]";>John D. McNally</a>
  * @author <a href="mailto:[email protected]";>Dave Bryson</a>
@@ -75,7 +72,7 @@ public class TemplateSessionValidator
             data.save();
         }
 
-        // make sure we have some way to return a response
+        // Make sure we have some way to return a response
         if (!data.hasScreen() && StringUtils.isEmpty(
                 data.getTemplateInfo().getScreenTemplate()))
         {
@@ -91,7 +88,7 @@ public class TemplateSessionValidator
             handleFormCounterToken(data, false);
         }
 
-        // we do not want to allow both a screen and template parameter.
+        // We do not want to allow both a screen and template parameter.
         // The template parameter is dominant.
         if (data.getTemplateInfo().getScreenTemplate() != null)
         {

Modified: 
turbine/core/trunk/src/java/org/apache/turbine/services/urlmapper/TurbineURLMapperService.java
URL: 
http://svn.apache.org/viewvc/turbine/core/trunk/src/java/org/apache/turbine/services/urlmapper/TurbineURLMapperService.java?rev=1886953&r1=1886952&r2=1886953&view=diff
==============================================================================
--- 
turbine/core/trunk/src/java/org/apache/turbine/services/urlmapper/TurbineURLMapperService.java
 (original)
+++ 
turbine/core/trunk/src/java/org/apache/turbine/services/urlmapper/TurbineURLMapperService.java
 Fri Feb 26 14:30:39 2021
@@ -52,6 +52,7 @@ import org.apache.turbine.util.uri.Turbi
 import org.apache.turbine.util.uri.URIParam;
 
 import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.json.JsonMapper;
 import com.fasterxml.jackson.dataformat.yaml.YAMLFactory;
 
 /**
@@ -93,14 +94,14 @@ public class TurbineURLMapperService
     private URLMappingContainer container;
 
     /**
-     * Regex pattern for group names
+     * Regex pattern for group names, equivalent to the characters defined in 
java {@link Pattern} (private) groupname method.
      */
     private static final Pattern NAMED_GROUPS_PATTERN = 
Pattern.compile("\\(\\?<([a-zA-Z][a-zA-Z0-9]*)>.+?\\)");
 
     /**
      * Regex pattern for multiple slashes
      */
-    private static final Pattern MULTI_SLASH_PATTERN = Pattern.compile("/+");
+    private static final Pattern MULTI_SLASH_PATTERN = Pattern.compile("[/]+");
 
     /**
      * Symbolic group name for context path
@@ -160,10 +161,6 @@ public class TurbineURLMapperService
                     .collect(Collectors.toSet());
 
             entryKeys.addAll(implicitKeysFound);
-            implicitKeysFound.forEach(key -> {
-                pathInfo.removeIf(uriParam -> key.equals(uriParam.getKey()));
-                queryData.removeIf(uriParam -> key.equals(uriParam.getKey()));
-            });
 
             if (entryKeys.containsAll(keys))
             {
@@ -195,9 +192,15 @@ public class TurbineURLMapperService
                 }
 
                 matcher.appendTail(sb);
+                
+                implicitKeysFound.forEach(key -> {
+                    pathInfo.removeIf(uriParam -> 
key.equals(uriParam.getKey()));
+                    queryData.removeIf(uriParam -> 
key.equals(uriParam.getKey()));
+                });
 
                 // Clean up
-                
uri.setScriptName(MULTI_SLASH_PATTERN.matcher(sb).replaceAll("/"));
+                
uri.setScriptName(MULTI_SLASH_PATTERN.matcher(sb).replaceAll("/").replaceFirst( 
"/$", "" ));
+                
                 break;
             }
         }
@@ -214,6 +217,7 @@ public class TurbineURLMapperService
     {
         for (URLMapEntry urlMap : container.getMapEntries())
         {
+            url = url.replaceFirst( "/$", "" );
             Matcher matcher = urlMap.getUrlPattern().matcher(url);
             if (matcher.matches())
             {
@@ -277,7 +281,7 @@ public class TurbineURLMapperService
                 container = mapper.readValue(reader, 
URLMappingContainer.class);
             } else if (configFile.endsWith(".json"))
             {
-                ObjectMapper mapper = new ObjectMapper();
+                ObjectMapper mapper = JsonMapper.builder().build();
                 container = mapper.readValue(reader, 
URLMappingContainer.class);
             }
         }

Modified: turbine/core/trunk/src/site/site.xml
URL: 
http://svn.apache.org/viewvc/turbine/core/trunk/src/site/site.xml?rev=1886953&r1=1886952&r2=1886953&view=diff
==============================================================================
--- turbine/core/trunk/src/site/site.xml (original)
+++ turbine/core/trunk/src/site/site.xml Fri Feb 26 14:30:39 2021
@@ -90,7 +90,8 @@
         <item name="Python Howto"        href="/howto/python-howto.html"/>
         <item name="Security Howto"      href="/howto/security-howto.html"/>
         <item name="Services Howto"      href="/howto/services-howto.html"/>
-        <item name="URL rewriting Howto" 
href="/howto/url-rewriting-howto.html"/>
+        <item name="URL Simplifier Howto" href="/howto/url-mapper-howto.html"/>
+        <item name="URL Rewriting Howto" 
href="/howto/url-rewriting-howto.html"/>
         <item name="Velocity Context Howto" href="/howto/context-howto.html"/>
         <item name="Velocity Site Howto" 
href="/howto/velocity-site-howto.html"/>
         <item name="VelocityOnlyLayout Howto" 
href="/howto/velocityonlylayout-howto.html"/>

Modified: 
turbine/core/trunk/src/test/org/apache/turbine/pipeline/DefaultLoginValveTest.java
URL: 
http://svn.apache.org/viewvc/turbine/core/trunk/src/test/org/apache/turbine/pipeline/DefaultLoginValveTest.java?rev=1886953&r1=1886952&r2=1886953&view=diff
==============================================================================
--- 
turbine/core/trunk/src/test/org/apache/turbine/pipeline/DefaultLoginValveTest.java
 (original)
+++ 
turbine/core/trunk/src/test/org/apache/turbine/pipeline/DefaultLoginValveTest.java
 Fri Feb 26 14:30:39 2021
@@ -146,6 +146,7 @@ public class DefaultLoginValveTest exten
         user = runData.getUser();
         assertNotNull(user);
         assertTrue(securityService.isAnonymousUser(user));
+        assertTrue(securityService.isAnonymousUser( 
(User)session.getAttribute( User.SESSION_KEY )));
         assertFalse(user.hasLoggedIn());
     }
 

Modified: 
turbine/core/trunk/src/test/org/apache/turbine/services/urlmapper/TurbineURLMapperJSONServiceTest.java
URL: 
http://svn.apache.org/viewvc/turbine/core/trunk/src/test/org/apache/turbine/services/urlmapper/TurbineURLMapperJSONServiceTest.java?rev=1886953&r1=1886952&r2=1886953&view=diff
==============================================================================
--- 
turbine/core/trunk/src/test/org/apache/turbine/services/urlmapper/TurbineURLMapperJSONServiceTest.java
 (original)
+++ 
turbine/core/trunk/src/test/org/apache/turbine/services/urlmapper/TurbineURLMapperJSONServiceTest.java
 Fri Feb 26 14:30:39 2021
@@ -88,7 +88,7 @@ public class TurbineURLMapperJSONService
     }
 
     @Test
-    public void testIgnoreParameterForShortURL() throws Exception
+    public void testDetailParameterForShortURL() throws Exception
     {
 
         PipelineData pipelineData = data;
@@ -115,19 +115,30 @@ public class TurbineURLMapperJSONService
         assertEquals( "scheme://bob/wow/damn2/page/Contact/role/anon", 
uri2.getAbsoluteLink() );
 
         uri2.addPathInfo( "language", "en" );
-        assertEquals( 
"scheme://bob/wow/damn2/page/Contact/role/anon/language/en", 
uri2.getAbsoluteLink() );
+        uri2.addQueryData( "kind", "4" );
+        assertEquals( 
"scheme://bob/wow/damn2/page/Contact/role/anon/language/en?kind=4", 
uri2.getAbsoluteLink() );
 
         urlMapper.mapToURL( uri2 );
-        String expectedMappedURL = "/wow/damn2/contact";
+//        String expectedMappedURL = "/wow/damn2/contact/4";
+        // not ignored
+        String expectedMappedURL = "/wow/damn2/contact/4/en";
+
         assertEquals( expectedMappedURL, uri2.getRelativeLink() );
 
         pp.clear();
+    
+//        
+        // scheme://bob/wow/damn2/contact/4/de
+        log.info( "relative uri is now {}", uri2.getRelativeLink() );
         urlMapper.mapFromURL( uri2.getRelativeLink(), pp );
 
         log.info( "parameters: {}", pp );
-        assertEquals( 2, pp.keySet().size() );
+        assertEquals( 4, pp.keySet().size() );
         assertEquals( "anon", pp.getString( "role" ) );
         assertEquals( "Contact", pp.getString( "page" ) );
+        assertEquals( "4", pp.getString( "kind" ) );
+        // not ignored
+        assertEquals( "en", pp.getString( "language" ) );
 
         uri2 = new TemplateURI( pipelineData.getRunData() );
         uri2.clearResponse();
@@ -137,6 +148,68 @@ public class TurbineURLMapperJSONService
         assertEquals( expectedMappedURL, uri2.getRelativeLink() );
 
     }
+    
+    @Test
+    public void testIgnoreParameterForShortURL() throws Exception
+    {
+
+        PipelineData pipelineData = data;
+
+        assertNotNull( urlMapper );
+
+        ParameterParser pp = pipelineData.get( Turbine.class, 
ParameterParser.class );
+        assertNotNull( pp );
+        assertTrue( pp.keySet().isEmpty() );
+        pp.clear();
+
+        urlMapper.mapFromURL( "/app/context/info", pp );
+
+        log.info( "parameters: {}", pp );
+        assertEquals( 2, pp.keySet().size() );
+        assertEquals( "anon", pp.getString( "role" ) );
+        assertEquals( "Info", pp.getString( "page" ) );
+
+        TemplateURI uri2 = new TemplateURI( pipelineData.getRunData() );
+        uri2.clearResponse();
+        uri2.addPathInfo( pp );
+
+        // this is an artifical url
+        assertEquals( "scheme://bob/wow/damn2/page/Info/role/anon", 
uri2.getAbsoluteLink() );
+
+        uri2.addPathInfo( "language", "en" );
+        uri2.addQueryData( "kind", "4" );
+        assertEquals( 
"scheme://bob/wow/damn2/page/Info/role/anon/language/en?kind=4", 
uri2.getAbsoluteLink() );
+
+        urlMapper.mapToURL( uri2 );
+
+        //  ignored
+        String expectedMappedURL = "/wow/damn2/info/4";
+
+        assertEquals( expectedMappedURL, uri2.getRelativeLink() );
+
+        pp.clear();
+       
+        uri2.addPathInfo( "de", "" );
+        // scheme://bob/wow/damn2/info/4/de/
+        log.info( "relative uri is now {}", uri2.getRelativeLink() );
+        urlMapper.mapFromURL( uri2.getRelativeLink(), pp );
+
+        log.info( "parameters: {}", pp );
+        assertEquals( 3, pp.keySet().size() );
+        assertEquals( "anon", pp.getString( "role" ) );
+        assertEquals( "Info", pp.getString( "page" ) );
+        assertEquals( "4", pp.getString( "kind" ) );
+        // language ignored
+
+        uri2 = new TemplateURI( pipelineData.getRunData() );
+        uri2.clearResponse();
+        uri2.addPathInfo( pp );
+
+        urlMapper.mapToURL( uri2 );
+        assertEquals( expectedMappedURL, uri2.getRelativeLink() );
+
+    }
+
 
     @Test
     public void testNonOptionalParameterForShortURL() throws Exception

Modified: turbine/core/trunk/xdocs/howto/index.xml
URL: 
http://svn.apache.org/viewvc/turbine/core/trunk/xdocs/howto/index.xml?rev=1886953&r1=1886952&r2=1886953&view=diff
==============================================================================
--- turbine/core/trunk/xdocs/howto/index.xml (original)
+++ turbine/core/trunk/xdocs/howto/index.xml Fri Feb 26 14:30:39 2021
@@ -43,7 +43,8 @@
         <li><a href="python-howto.html">Python Howto</a></li>
         <li><a href="security-howto.html">Security Howto</a></li>
         <li><a href="services-howto.html">Services Howto</a></li>
-        <li><a href="url-rewriting-howto.html">URL rewriting Howto</a></li>
+        <li><strong>NEW!</strong> <a href="url-mapper-howto.html">URL 
Simplifier Howto</a></li>
+        <li><a href="url-rewriting-howto.html">URL Rewriting Howto</a></li>
         <li><a href="context-howto.html">Velocity Context Howto</a></li>
         <li><a href="velocity-site-howto.html">Velocity Site Howto</a></li>
         <li><a href="velocityonlylayout-howto.html">VelocityOnlyLayout 
Howto</a></li>

Modified: turbine/core/trunk/xdocs/howto/migrate-from-4_0-howto.xml
URL: 
http://svn.apache.org/viewvc/turbine/core/trunk/xdocs/howto/migrate-from-4_0-howto.xml?rev=1886953&r1=1886952&r2=1886953&view=diff
==============================================================================
--- turbine/core/trunk/xdocs/howto/migrate-from-4_0-howto.xml (original)
+++ turbine/core/trunk/xdocs/howto/migrate-from-4_0-howto.xml Fri Feb 26 
14:30:39 2021
@@ -154,7 +154,7 @@
 </section>
 
 
-<section name="Migrating to Functioal Interfaces and Rundata">
+<section name="Migrating to Functional Interfaces and Rundata">
        
        <p>Functional interfaces are now used instead of abstract classes. 
Rundata should be removed and instead of PipelineData used, but we keep it for 
now. 
      As a result <strong>AbstractValve was removed</strong> and with it the 
method <strong>getRunData(pipelineData)</strong> is gone.
@@ -193,7 +193,7 @@
 
 
 
-<section name="Migrating file upload to Parts">
+<section name="Migrating File Upload to Parts">
        
        <p>
                In turbine-4.0.1 and prior, file uploads were processed through 
the

Modified: turbine/core/trunk/xdocs/howto/services-howto.xml
URL: 
http://svn.apache.org/viewvc/turbine/core/trunk/xdocs/howto/services-howto.xml?rev=1886953&r1=1886952&r2=1886953&view=diff
==============================================================================
--- turbine/core/trunk/xdocs/howto/services-howto.xml (original)
+++ turbine/core/trunk/xdocs/howto/services-howto.xml Fri Feb 26 14:30:39 2021
@@ -203,7 +203,7 @@ TurbineFoo.fooMethod1();
     </p>
 
     <p>
-      init() and shutdown() applies to Turbine 2.1/2.2 This might change
+      init() and shutdown() applies to Turbine 2-5 This might change
       with the lifecycle interfaces in a later release.
     </p>
 </section>

Modified: turbine/core/trunk/xdocs/howto/url-mapper-howto.xml
URL: 
http://svn.apache.org/viewvc/turbine/core/trunk/xdocs/howto/url-mapper-howto.xml?rev=1886953&r1=1886952&r2=1886953&view=diff
==============================================================================
--- turbine/core/trunk/xdocs/howto/url-mapper-howto.xml (original)
+++ turbine/core/trunk/xdocs/howto/url-mapper-howto.xml Fri Feb 26 14:30:39 2021
@@ -21,71 +21,113 @@
 <document>
 
  <properties>
-  <title>URL Mapper Howto</title>
+  <title>URL Simplifier Howto</title>
  </properties>
 
 <body>
 
-<section>
+<section name="Introduction">
 
 <p>
-Unaltered Turbine URLs look like this:
+Unaltered Turbine URLs may look like this:
 
<code>http://www.foo.com:8080/CONTEXT/servlet/MAPPING/template/Foo.vm</code>.<br/>
-But you want shorter URLs, or you don't like exposing the use of
-servlets in the URL.  Maybe this url would suit you better:
-<code>http://www.foo.com:8080/beautiful/world</code>
+But you want shorter URLs Maybe this url would suit you better:
+<code>http://www.foo.com:8080/CONTEXT/servlet/beautiful/world</code>
 </p>
 
+This HOWTO describes, how you can control the pathinfo or query part of a url 
(behind the webapproot and the context) and the context with a mapping 
(routing) file 
+defined in xml, json or yaml format to become more simplified or beautiful! 
 
 </section>
 
 <section name="Turbine Configuration">
 
 <p>
-You need to register the URL Mapper service in the pipeline by adding the 
service, the configuration 
+You need to
+<ul>
+<li>register the URL Mapper service in turbine configuration (TR.properties) 
</li>
+<li>register the valve in the pipeline (turbine-classic-pipeline.xml)</li>
+</ul> 
 </p>
 
-<p>
-In TurbineResources.properties, search URLMapperService, and if not found, add 
the following settings:
+
+<p>Consider the following example configuration:
+
+MappedTemplateLink is for now optional, you can add it as a separate tool or 
just replace the existing TemplateLink.
 </p>
 
 <source><![CDATA[
+       # -------------------------------------------------------------------
+       #
+       #  U R L  M A P P E R  S E R V I C E
+       #
+       # -------------------------------------------------------------------
+       
+       # required
+       
services.URLMapperService.classname=org.apache.turbine.services.urlmapper.TurbineURLMapperService
+       
+       # configFile is required here! xml, json and yml supported as extension.
+       services.URLMapperService.configFile = /conf/turbine-url-mapping.xml
+       
+       # new mapper (optional)
+       
tool.request.mlink=org.apache.turbine.services.urlmapper.MappedTemplateLink
+       # tool.request.jlink= 
org.apache.turbine.services.pull.tools.TemplateLink
+]]></source>
+
+<p>To resolve a provided / mapped URL add the valve into pipeline 
(pipeline.default.descriptor = /conf/turbine-classic-pipeline.xml). 
+</p>
+
+<source><![CDATA[
+  <valves>
+    <valve>org.apache.turbine.services.urlmapper.URLMapperValve</valve>
+    ...
 
-# -------------------------------------------------------------------
-#
-#  U R L  M A P P E R  S E R V I C E
-#
-# -------------------------------------------------------------------
+]]></source>
+
+<p>This will check if the provided URL matches any pattern, resolves it given 
in the path or implicitly as defined in
+
+the URLMapperService's configfile.</p> 
 
-# new mapper
-tool.request.mlink=org.apache.turbine.services.urlmapper.MappedTemplateLink
+</section>
 
-services.URLMapperService.classname=org.apache.turbine.services.urlmapper.TurbineURLMapperService
+<section name="URL Mapping Mechanism">
 
-# xml, json and yml supported as extension
-services.URLMapperService.configFile = /conf/turbine-url-mapping.xml
+<p>The pattern format scheme is as follows, e.g. in JSON:</p>
 
+<source><![CDATA[
+ "pattern":  
"/(?<webAppRoot>[.\\-\\w]+)/(?<contextPath>\\w+)/(?<resolvableParam>\\w+)/beautifulname"
 ]]></source>
 
-<p>Add the valve into pipeline (pipeline.default.descriptor = 
/conf/turbine-classic-pipeline.xml). 
-</p>
+<p>That is any specific parameter name or key, which should be resolved, has 
to be set like this</p> 
 
 <source><![CDATA[
-  <valves>
-    <valve>org.apache.turbine.services.urlmapper.URLMapperValve</valve>
-    ...
+ /(?<resolvableParam>\\w+)
+]]></source>
+
+<p>Another condition to be met, is that the parameter name must follow the 
"Java Named Group pattern characters restriction":</p>
 
+<source><![CDATA[
+ NAMED_GROUPS_PATTERN = Pattern.compile("(?<([a-zA-Z][a-zA-Z0-9]*)>.+?)");
 ]]></source>
 
-<p>This will read the beautfied URL and alter into to what, the server 
requires as defined 
-in the URLMapperService's configfile . 
+<p>
+Any parameter is resolved as a <i>group name</i>
+ (<a 
href="https://docs.oracle.com/javase/8/docs/api/java/util/regex/Pattern.html";>Java
 Pattern->Groups and Capturing->Group name</a>).
+ 
+These group names are predefined (symbolic group name)):
+ 
+<ul><li><strong>&lt;webAppRoot&gt;</strong></li><li><strong>&lt;contextPath&gt;</strong></li></ul>
+
+Be aware, that this does not allow replacing parameters containing other 
characters (e.g underscore or hyphens). You may use implicit parameter 
matching. 
+
+Following is an example for a configuration : 
 </p>
 
 <source><![CDATA[
 <url-mapping name="default">
     <maps>
         <map>
-            
<pattern>/(?&lt;contextPath&gt;\w+)/book/(?&lt;bookId&gt;\d+)</pattern>
+            
<pattern>/(?&lt;webAppRoot&gt;[.\\-\\w]+)/(?&lt;contextPath&gt;\w+)/book/(?&lt;bookId&gt;\d+)</pattern>
             <implicit-parameters>
                 <parameter key="template">Book.vm</parameter>
                 <parameter key="detail">0</parameter>
@@ -94,16 +136,98 @@ in the URLMapperService's configfile .
         ...
 ]]></source>
 
+<p>Three parameters are evaluated:
+
+<ul><li>a parameter name <strong>template</strong> and value 
<strong>Book.vm</strong></li>
+<li>a parameter <strong>detail</strong> and value <strong>0</strong></li>
+<li>a parameter <strong>bookId</strong> with <i>any</i> value, e.g. 
<strong>4</strong></li>
+</ul>
+This will be converted, if matched, to an URL like <strong>/book/4</strong>. 
+The pattern uses type restrictions for the value, e.g. number for the bookId 
and a extended character set for the webAppRoot, which will be applied in (back 
resolving) <strong>mapFromURL</strong>.
+</p>
+
+<p>Another example in <strong>JSON</strong> format with just more short URL by 
replacing two parameters:</p>
+
+<source><![CDATA[
+{
+  "name": "default",
+  "maps": [
+       {
+               "pattern": 
"/(?<webAppRoot>[\\w]+)/(?<contextPath>\\w+)/register",
+               "implicit-parameters": {
+                       "page": "Register",
+                       "role": "anon"
+               }
+       },
+        ...
+]]></source>
+
+</section>
+
+<section name="Turbine Service Description and Usage">
+
+<p>The main methods of the service <strong>TurbineURLMapperService</strong> 
are</p> 
+
+<ul>
+<li><strong>mapToUrl</strong>, which as the Javadoc explains "maps a set of 
parameters (contained in TurbineURI PathInfo and QueryData) to a 
TurbineURIs"</li>
+<li><strong>mapFromUrl</strong>, which "maps a simplified URL to a set of 
parameters"</li>
+</ul> 
+
+  <subsection name="Matrix">
+      <table>
+        <tr>
+         <th colspan="6">Turbine URL Simplifier Mapping Model</th>
+        </tr>
+        <tr>
+          <th>Mechanism</th><th>Method</th><th>Pattern</th><th>Implicit 
Param</th><th>Override Param</th><th>Ignore Param</th>
+        </tr>
+       
+        <tr><th>Converts Parameterized URL to simplified 
URL</th><th>mapToUrl</th><td>
+         "Match Group Name": The pattern of the target URL after evaluation of 
parameters. If a group name is set, a matching parameter key must be provided 
and the value will replace the group name in the target URL.</td>
+         <td>"Exact Filter", "Reduce": If a parameter key is is set 
implicitely, both key and value must exactly matched by a parameter pair in the 
provided (unmapped) URI. It will then be removed</td>
+         <td>- An override could be achieved by hard coding it in the pattern 
and filterign in implicit param. 
+         On the other hand you can then ignore the parameter</td>
+         <td>The parameter will be removed from the required parameter key set 
and also from the target URL if it is provided as a group name</td></tr>
+        
+        <tr><th>Resolves URL to Params for evaluating by the 
backend</th><th>mapFromUrl</th><td>
+        The pattern of the URL to be matched to evaluate parameter 
resolving</td>
+        <td>Param key/value will be set implicitely</td>
+        <td>Overrides (provided) URL parameter with provided value</td>
+        <td>will remove parameter key/value from result parameter list, even 
if provided as capturing group name</td></tr>
+      </table>
+    </subsection>
+    
+   <p>N.B. Symbolic group names wenapproot and context could not be ignored or 
overridden!</p>
+
 <p>
-Use it in the templates, e.g.
+The convenience class MappedTemplateLink class (of type TemplateLink) calls 
with its methods getRelative or getAbsoluteLink mapToUrl implicitely. 
+Use it in a velocity template like this:
 </p>
 
 <source><![CDATA[
-    $mlink.addPathInfo("world","nice").getRelativeLink()
-    ## may result into /beautiful/world
+  $mlink.addPathInfo("world","nice").getRelativeLink()
+  ## may result into /beautiful/world
 ]]></source>
 
 <p>
+<p>Alternatively you can use the service explicitely in Java, e.g. in a Java 
Action or other class:</p>
+
+<source><![CDATA[
+   // inside any assembler you may alternatively use annotation 
@TurbineService( "URLMapperService" ) urlMapper;
+   
+  URLMapperService urlMapper = (URLMapperService) 
TurbineServices.getInstance().getService(URLMapperService.SERVICE_NAME);
+
+  // Any turbineURI ..e.g. from PoolService or 
+  TurbineURI uri  ... 
+          
+  urlMapper.mapToURL( uri );
+  
+  // use it, e.g by putting it into a velocity context 
(org.apache.velocity.context.Context(
+  context.put("myLink", link);
+     
+]]></source>
+
+ 
 More examples ...
 </p>
 


Reply via email to