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><webAppRoot></strong></li><li><strong><contextPath></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>/(?<contextPath>\w+)/book/(?<bookId>\d+)</pattern>
+
<pattern>/(?<webAppRoot>[.\\-\\w]+)/(?<contextPath>\w+)/book/(?<bookId>\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>