You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@turbine.apache.org by gk...@apache.org on 2021/02/03 15:42:23 UTC

svn commit: r1886168 - in /turbine/core/trunk: ./ conf/ conf/test/ src/java/org/apache/turbine/services/urlmapper/ src/test/org/apache/turbine/services/urlmapper/ src/test/org/apache/turbine/services/urlmapper/model/ xdocs/howto/

Author: gk
Date: Wed Feb  3 15:42:22 2021
New Revision: 1886168

URL: http://svn.apache.org/viewvc?rev=1886168&view=rev
Log:
- update yauaa to 5.21 ( CVE-2020-13956)
- update junit (CVE-2020-15250)
- add JSON url mapper (capability already included) and test
- TurbineURLMapperService: Adding behaviour for ignore parameter as capturing group: will ignore parameter value in mapToUrl. Example in turbine-url-mapping.json
- fix defaultOnBorrow warning
- add missing yaml test and TR.properties
- add xdoc draft for url mapper

Added:
    turbine/core/trunk/conf/test/TurbineURLMapperYAMLServiceTest.properties
    turbine/core/trunk/conf/turbine-url-mapping.json
    turbine/core/trunk/src/test/org/apache/turbine/services/urlmapper/TurbineURLMapperJSONServiceTest.java
    turbine/core/trunk/src/test/org/apache/turbine/services/urlmapper/TurbineURLMapperYAMLServiceTest.java
      - copied, changed from r1886167, turbine/core/trunk/src/test/org/apache/turbine/services/urlmapper/TurbineYamlURLMapperServiceTest.java
    turbine/core/trunk/xdocs/howto/url-mapper-howto.xml
Removed:
    turbine/core/trunk/src/test/org/apache/turbine/services/urlmapper/TurbineYamlURLMapperServiceTest.java
Modified:
    turbine/core/trunk/conf/test/TorqueTest.properties
    turbine/core/trunk/conf/test/TurbineURLMapperServiceTest.properties
    turbine/core/trunk/conf/turbine-url-mapping.yml
    turbine/core/trunk/pom.xml
    turbine/core/trunk/src/java/org/apache/turbine/services/urlmapper/TurbineURLMapperService.java
    turbine/core/trunk/src/test/org/apache/turbine/services/urlmapper/model/YamlURLMappingContainerTest.java

Modified: turbine/core/trunk/conf/test/TorqueTest.properties
URL: http://svn.apache.org/viewvc/turbine/core/trunk/conf/test/TorqueTest.properties?rev=1886168&r1=1886167&r2=1886168&view=diff
==============================================================================
--- turbine/core/trunk/conf/test/TorqueTest.properties (original)
+++ turbine/core/trunk/conf/test/TorqueTest.properties Wed Feb  3 15:42:22 2021
@@ -18,7 +18,7 @@
 torque.applicationRoot = .
 pipeline.default.descriptor = conf/turbine-classic-pipeline.xml
 # torque.defaults.pool.defaultMaxActive=30
-torque.defaults.pool.testOnBorrow=true
+torque.defaults.pool.defaultTestOnBorrow=true
 torque.defaults.pool.validationQuery=SELECT 1
 
 torque.idbroker.cleverquantity=true
@@ -32,7 +32,7 @@ torque.database.default.adapter=hsqldb
 # dbcp2 
 torque.dsfactory.default.factory= org.apache.torque.dsfactory.SharedPool2DataSourceFactory
 
-torque.dsfactory.default.pool.testOnBorrow=true
+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:.

Modified: turbine/core/trunk/conf/test/TurbineURLMapperServiceTest.properties
URL: http://svn.apache.org/viewvc/turbine/core/trunk/conf/test/TurbineURLMapperServiceTest.properties?rev=1886168&r1=1886167&r2=1886168&view=diff
==============================================================================
--- turbine/core/trunk/conf/test/TurbineURLMapperServiceTest.properties (original)
+++ turbine/core/trunk/conf/test/TurbineURLMapperServiceTest.properties Wed Feb  3 15:42:22 2021
@@ -127,7 +127,24 @@ services.AvalonComponentService.lookup =
 
 # -------------------------------------------------------------------
 #
+#  P U L L  S E R V I C E
+#
+# -------------------------------------------------------------------
+
+# services.PullService.classname=org.apache.turbine.services.pull.TurbinePullService
+
+# These tools will be made available to all your
+# templates. You list the tools in the following way:
+#
+# tool.<scope>.<id> = <classname>
+
+# tool.request.mlink=org.apache.turbine.services.urlmapper.MappedTemplateLink
+
+
+# -------------------------------------------------------------------
+#
 #  U R L  M A P P E R  S E R V I C E
 #
 # -------------------------------------------------------------------
+
 services.URLMapperService.configFile = /conf/turbine-url-mapping.xml

Added: turbine/core/trunk/conf/test/TurbineURLMapperYAMLServiceTest.properties
URL: http://svn.apache.org/viewvc/turbine/core/trunk/conf/test/TurbineURLMapperYAMLServiceTest.properties?rev=1886168&view=auto
==============================================================================
--- turbine/core/trunk/conf/test/TurbineURLMapperYAMLServiceTest.properties (added)
+++ turbine/core/trunk/conf/test/TurbineURLMapperYAMLServiceTest.properties Wed Feb  3 15:42:22 2021
@@ -0,0 +1,22 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#   http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+
+# override
+services.URLMapperService.configFile = /conf/turbine-url-mapping.yml
+
+include = TurbineURLMapperServiceTest.properties
+

Added: turbine/core/trunk/conf/turbine-url-mapping.json
URL: http://svn.apache.org/viewvc/turbine/core/trunk/conf/turbine-url-mapping.json?rev=1886168&view=auto
==============================================================================
--- turbine/core/trunk/conf/turbine-url-mapping.json (added)
+++ turbine/core/trunk/conf/turbine-url-mapping.json Wed Feb  3 15:42:22 2021
@@ -0,0 +1,45 @@
+{
+	"name": "default",
+	"maps": [
+		{
+			"pattern": "/(?<webAppRoot>[\\w]+)/(?<contextPath>\\w+)/register",
+			"implicit-parameters": {
+				"page": "Register",
+				"role": "anon"
+			}
+		},
+		{
+            "pattern": "/(?<webAppRoot>[\\w]+)/(?<contextPath>\\w+)/(?<language>\\w+)/register",
+            "implicit-parameters": {
+                "page": "Register",
+                "role": "anon"
+            },
+            "override-parameters": {
+                "role": "anon"
+            }
+        },
+        {
+            "pattern": "/(?<webAppRoot>[\\w]+)/(?<contextPath>\\w+)/contact",
+            "implicit-parameters": {
+                "page": "Contact",
+                "role": "anon"
+            },
+            "override-parameters": {
+                "role": "anon"
+            }
+        },
+		{
+            "pattern": "/(?<webAppRoot>[\\w]+)/(?<contextPath>\\w+)/(?<language>\\w+)/contact",
+            "implicit-parameters": {
+                "page": "Contact",
+                "role": "anon"
+            },
+            "override-parameters": {
+                "role": "anon"
+            },
+            "ignore-parameters": {
+                "language": null
+            }
+        }
+	]
+}
\ No newline at end of file

Modified: turbine/core/trunk/conf/turbine-url-mapping.yml
URL: http://svn.apache.org/viewvc/turbine/core/trunk/conf/turbine-url-mapping.yml?rev=1886168&r1=1886167&r2=1886168&view=diff
==============================================================================
--- turbine/core/trunk/conf/turbine-url-mapping.yml (original)
+++ turbine/core/trunk/conf/turbine-url-mapping.yml Wed Feb  3 15:42:22 2021
@@ -1,4 +1,3 @@
-
 name: default
 maps:
     - pattern: /(?<contextPath>\w+)/book/(?<bookId>\d+)
@@ -10,22 +9,22 @@ maps:
         template: Book.vm
       ignore-parameters:
         view: null
-    - pattern: /(?<contextPath>\w+)/register
+    - pattern: /(?<webAppRoot>[\.\-\w]+)(?<contextPath>\w+)/register
       implicit-parameters:
         media-type: html
         role: anon
         template: Registerone.vm
         js_pane: random-id-123-abc
-    - pattern: /(?<contextPath>\w+)/contact
+    - pattern: /(?<webAppRoot>[\.\-\w]+)(?<contextPath>\w+)/contact
       implicit-parameters:
         media-type: html
         page: Contact
         js_pane: another-random-id-876-dfg       
         role: anon
       override-parameters:
-        role: anon
+        role: anon  
     - pattern: /(?<contextPath>\w+)/(?<id>\d+)/(?<role>\w+)/(?<language>\w+)
       implicit-parameters:
         media-type: html
-        template: default.vm    
+        template: default.vm 
                 
\ No newline at end of file

Modified: turbine/core/trunk/pom.xml
URL: http://svn.apache.org/viewvc/turbine/core/trunk/pom.xml?rev=1886168&r1=1886167&r2=1886168&view=diff
==============================================================================
--- turbine/core/trunk/pom.xml (original)
+++ turbine/core/trunk/pom.xml Wed Feb  3 15:42:22 2021
@@ -22,7 +22,7 @@
   <parent>
     <groupId>org.apache.turbine</groupId>
     <artifactId>turbine-parent</artifactId>
-    <version>7</version>
+    <version>8-SNAPSHOT</version>
   </parent>
   <artifactId>turbine</artifactId>
   <name>Apache Turbine</name>
@@ -532,6 +532,7 @@
     <plugins>
 
      <plugin>
+       <!-- hint: mvn verify  -->
         <groupId>org.owasp</groupId>
         <artifactId>dependency-check-maven</artifactId>
         <configuration>
@@ -900,7 +901,7 @@
     <dependency>
       <groupId>nl.basjes.parse.useragent</groupId>
       <artifactId>yauaa</artifactId>
-      <version>5.19</version>
+      <version>5.21</version>
     </dependency>
     <dependency>
       <groupId>org.apache.fulcrum</groupId>
@@ -970,11 +971,6 @@
       </exclusions>
     </dependency>
     <!-- use default dbcp2 from torque-runtime -->
-    <!--dependency> 
-        <groupId>commons-dbcp</groupId>
-        <artifactId>commons-dbcp</artifactId>
-        <version>1.4</version>
-    </dependency-->
     <dependency>
          <groupId>commons-configuration</groupId>
          <artifactId>commons-configuration</artifactId>
@@ -1108,10 +1104,16 @@
       <scope>test</scope>
       <optional>true</optional>
     </dependency>
-    <!-- do not add junit 4 support e.g. with org.junit.platform runner or launcher,
+     <dependency>
+        <groupId>junit</groupId>
+        <artifactId>junit</artifactId>
+        <version>4.13.1</version>
+        <scope>test</scope>
+      </dependency>
+      <!-- do not add junit 4 support e.g. with org.junit.platform runner or launcher,
           as it is not compatible with jupiter tags, will throw 
          [WARNING] Couldn't load group class 'docker' in Surefire|Failsafe plugin
-    -->
+       -->
   </dependencies>
 
   <profiles>
@@ -1252,6 +1254,7 @@
       <activation>
         <activeByDefault>false</activeByDefault>
       </activation>
+      <!-- mvn test -Dtest=TurbineURLMapperYAMLServiceTest -Pyaml -->
       <build>
       <plugins>
             <plugin>

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=1886168&r1=1886167&r2=1886168&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 Wed Feb  3 15:42:22 2021
@@ -182,18 +182,21 @@ public class TurbineURLMapperService
                         matcher.appendReplacement(sb, uri.getScriptName());
                     } else
                     {
+                        boolean ignore = urlMap.getIgnoreParameters().keySet().stream()
+                                .anyMatch( x-> x.equals( key ) );
                         matcher.appendReplacement(sb,
-                                Matcher.quoteReplacement(
-                                        Objects.toString(uriParameterMap.get(key))));
+                                 Matcher.quoteReplacement(
+                                        (!ignore)? Objects.toString(uriParameterMap.get(key)):""));
                         // Remove handled parameters (all of them!)
                         uri.removePathInfo(key);
                         uri.removeQueryData(key);
                     }
                 }
-
+                
                 matcher.appendTail(sb);
+                
                 // Clean up
-                uri.setScriptName(sb.toString().replace("//", "/"));
+                uri.setScriptName(sb.toString().replaceAll("/+", "/"));
                 break;
             }
         }
@@ -276,6 +279,10 @@ public class TurbineURLMapperService
                 // which is not what we need here -> java object deserialization.
                 ObjectMapper mapper = new ObjectMapper(new YAMLFactory());
                 container = mapper.readValue(reader, URLMappingContainer.class);
+            } else if (configFile.endsWith(".json"))
+            {
+                ObjectMapper mapper = new ObjectMapper();
+                container = mapper.readValue(reader, URLMappingContainer.class);
             }
         }
         catch (IOException | JAXBException e)

Added: 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=1886168&view=auto
==============================================================================
--- turbine/core/trunk/src/test/org/apache/turbine/services/urlmapper/TurbineURLMapperJSONServiceTest.java (added)
+++ turbine/core/trunk/src/test/org/apache/turbine/services/urlmapper/TurbineURLMapperJSONServiceTest.java Wed Feb  3 15:42:22 2021
@@ -0,0 +1,193 @@
+package org.apache.turbine.services.urlmapper;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+import static org.mockito.Mockito.mock;
+
+import javax.servlet.ServletConfig;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.fulcrum.parser.ParameterParser;
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
+import org.apache.turbine.Turbine;
+import org.apache.turbine.pipeline.PipelineData;
+import org.apache.turbine.services.TurbineServices;
+import org.apache.turbine.test.BaseTestCase;
+import org.apache.turbine.util.RunData;
+import org.apache.turbine.util.TurbineConfig;
+import org.apache.turbine.util.uri.TemplateURI;
+import org.junit.jupiter.api.AfterAll;
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.mockito.Mockito;
+
+public class TurbineURLMapperJSONServiceTest extends BaseTestCase
+{
+
+    private static TurbineConfig tc = null;
+
+    private static URLMapperService urlMapper = null;
+
+    private RunData data;
+
+    Logger log = LogManager.getLogger();
+
+    @BeforeAll
+    public static void setUp() throws Exception
+    {
+        tc = new TurbineConfig( ".", "/conf/test/TurbineURLMapperJSONServiceTest.properties" );
+        tc.initialize();
+
+        urlMapper = (URLMapperService) TurbineServices.getInstance().getService( URLMapperService.SERVICE_NAME );
+    }
+
+    @AfterAll
+    public static void tearDown() throws Exception
+    {
+        if (tc != null)
+        {
+            tc.dispose();
+        }
+    }
+
+    @BeforeEach
+    public void init() throws Exception
+    {
+
+        ServletConfig config = tc.getTurbine().getServletConfig();
+        // mock(ServletConfig.class);
+        HttpServletRequest request = getMockRequest();
+        HttpServletResponse response = mock( HttpServletResponse.class );
+
+        data = getRunData( request, response, config );
+
+        Mockito.when( response.encodeURL( Mockito.anyString() ) )
+                .thenAnswer( invocation -> invocation.getArgument( 0 ) );
+    }
+
+    @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/contact", pp );
+
+        log.info( "parameters: {}", pp );
+        assertEquals( 2, pp.keySet().size() );
+        assertEquals( "anon", pp.getString( "role" ) );
+        assertEquals( "Contact", 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/Contact/role/anon", uri2.getAbsoluteLink() );
+
+        uri2.addPathInfo( "language", "en" );
+        assertEquals( "scheme://bob/wow/damn2/page/Contact/role/anon/language/en", uri2.getAbsoluteLink() );
+
+        urlMapper.mapToURL( uri2 );
+        String expectedMappedURL = "/wow/damn2/contact";
+        assertEquals( expectedMappedURL, uri2.getRelativeLink() );
+
+        pp.clear();
+        urlMapper.mapFromURL( uri2.getRelativeLink(), pp );
+
+        log.info( "parameters: {}", pp );
+        assertEquals( 2, pp.keySet().size() );
+        assertEquals( "anon", pp.getString( "role" ) );
+        assertEquals( "Contact", pp.getString( "page" ) );
+
+        uri2 = new TemplateURI( pipelineData.getRunData() );
+        uri2.clearResponse();
+        uri2.addPathInfo( pp );
+
+        urlMapper.mapToURL( uri2 );
+        assertEquals( expectedMappedURL, uri2.getRelativeLink() );
+
+    }
+
+    @Test
+    public void testNonOptionalParameterForShortURL() 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( "/wow/damn2/register", pp );
+
+        log.info( "parameters: {}", pp );
+        assertEquals( 2, pp.keySet().size() );
+        assertEquals( "anon", pp.getString( "role" ) );
+        assertEquals( "Register", 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/Register/role/anon", uri2.getAbsoluteLink() );
+
+        uri2.addPathInfo( "language", "en" );
+        assertEquals( "scheme://bob/wow/damn2/page/Register/role/anon/language/en", uri2.getAbsoluteLink() );
+
+        urlMapper.mapToURL( uri2 );
+        String expectedMappedURL = "/wow/damn2/en/register";
+        assertEquals( expectedMappedURL, uri2.getRelativeLink() );
+
+        pp.clear();
+        urlMapper.mapFromURL( uri2.getRelativeLink(), pp );
+
+        log.info( "parameters: {}", pp );
+        assertEquals( 3, pp.keySet().size() );
+        assertEquals( "anon", pp.getString( "role" ) );
+        assertEquals( "Register", pp.getString( "page" ) );
+        assertEquals( "en", pp.getString( "language" ) );
+
+        uri2 = new TemplateURI( pipelineData.getRunData() );
+        uri2.clearResponse();
+        uri2.addPathInfo( pp );
+
+        urlMapper.mapToURL( uri2 );
+        assertEquals( expectedMappedURL, uri2.getRelativeLink() );
+
+    }
+
+}

Copied: turbine/core/trunk/src/test/org/apache/turbine/services/urlmapper/TurbineURLMapperYAMLServiceTest.java (from r1886167, turbine/core/trunk/src/test/org/apache/turbine/services/urlmapper/TurbineYamlURLMapperServiceTest.java)
URL: http://svn.apache.org/viewvc/turbine/core/trunk/src/test/org/apache/turbine/services/urlmapper/TurbineURLMapperYAMLServiceTest.java?p2=turbine/core/trunk/src/test/org/apache/turbine/services/urlmapper/TurbineURLMapperYAMLServiceTest.java&p1=turbine/core/trunk/src/test/org/apache/turbine/services/urlmapper/TurbineYamlURLMapperServiceTest.java&r1=1886167&r2=1886168&rev=1886168&view=diff
==============================================================================
--- turbine/core/trunk/src/test/org/apache/turbine/services/urlmapper/TurbineYamlURLMapperServiceTest.java (original)
+++ turbine/core/trunk/src/test/org/apache/turbine/services/urlmapper/TurbineURLMapperYAMLServiceTest.java Wed Feb  3 15:42:22 2021
@@ -18,10 +18,9 @@ package org.apache.turbine.services.urlm
  * specific language governing permissions and limitations
  * under the License.
  */
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertTrue;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertTrue;
 import static org.mockito.Mockito.mock;
 
 import javax.servlet.ServletConfig;
@@ -46,150 +45,158 @@ import org.junit.jupiter.api.Test;
 import org.mockito.Mockito;
 
 @Tag("yaml")
-public class TurbineYamlURLMapperServiceTest extends BaseTestCase {
-	
-	private static TurbineConfig tc = null;
-
-	private static URLMapperService urlMapper = null;
-
-	private RunData data;
-	
-	Logger log = LogManager.getLogger();
-
-	@BeforeAll
-	public static void setUp() throws Exception {
-		tc = new TurbineConfig(".", "/conf/test/TurbineYamlURLMapperServiceTest.properties");
-		tc.initialize();
-
-		urlMapper = (URLMapperService) TurbineServices.getInstance().getService(URLMapperService.SERVICE_NAME);
-	}
-
-	@AfterAll
-	public static void tearDown() throws Exception {
-		if (tc != null) {
-			tc.dispose();
-		}
-	}
-
-	@BeforeEach
-	public void init() throws Exception {
-
-		ServletConfig config = tc.getTurbine().getServletConfig();
-		// mock(ServletConfig.class);
-		HttpServletRequest request = getMockRequest();
-		HttpServletResponse response = mock(HttpServletResponse.class);
-
-		data = getRunData(request, response, config);
-		
-		Mockito.when(response.encodeURL(Mockito.anyString())).thenAnswer(invocation -> invocation.getArgument(0));
-	}
-
-	@Test
-	public void testMapToAnotherURL() throws Exception {
-
-		PipelineData pipelineData = data;
-
-		assertNotNull(urlMapper);
-
-		TemplateURI uri = new TemplateURI(pipelineData.getRunData());
-		uri.addPathInfo("id", 1234);
-		uri.addPathInfo("role", "guest");
-		uri.addPathInfo("language", "de");
-
-		String unMappedURL = uri.getAbsoluteLink(); // scheme://bob/wow/damn2/id/1234/role/guest
-
-		urlMapper.mapToURL(uri);
-		urlMapper.mapToURL(uri); // should be idempotent
-
-		String mappedLink = uri.getRelativeLink(); // wow/damn2/id/1234/role/guest
-		log.info(unMappedURL);
-		log.info(mappedLink);
-
-		String expectedMappedURL = "/wow/1234/guest/de";
-		String expectedRawURL = "scheme://bob/wow/damn2/id/1234/role/guest/language/de";
-		// raw url
-		assertEquals(expectedRawURL, unMappedURL);
-		assertEquals(expectedMappedURL, mappedLink);
-
-		ParameterParser pp = pipelineData.get(Turbine.class, ParameterParser.class);
-		assertNotNull(pp);
-		assertTrue(pp.keySet().isEmpty());
-		urlMapper.mapFromURL(mappedLink, pp);
-
-		assertEquals(5, pp.keySet().size());
-		assertEquals(1234, pp.getInt("id"));
-		assertEquals("guest", pp.getString("role"));
-		assertEquals("de", pp.getString("language"));
-		assertEquals("html", pp.getString("media-type"));
-
-		TemplateURI uri2 = new TemplateURI(pipelineData.getRunData());
-		uri2.clearResponse();
-		uri2.setTemplate("default.vm");
-		uri2.addPathInfo(pp);
-		// this is an artifical url
-		assertEquals("scheme://bob/wow/damn2/template/default.vm/media-type/html/role/guest/id/1234/language/de",
-				uri2.getAbsoluteLink());
-		urlMapper.mapToURL(uri2);
-		assertEquals(expectedMappedURL, uri2.getRelativeLink());
-	}
-
-	@Test
-	public void testOverrideShortURL() throws Exception {
-
-		PipelineData pipelineData = data;
-		
-		assertNotNull(urlMapper);
-
-		ParameterParser pp = pipelineData.get(Turbine.class, ParameterParser.class);
-		assertNotNull(pp);
-		assertTrue(pp.keySet().isEmpty());
-		
-		pp.add("role", "admin"); // will not be overridden
-		urlMapper.mapFromURL("/app/register", pp);
-
-		assertEquals(4, pp.keySet().size());
-		assertEquals("random-id-123-abc", pp.getString("js_pane"));
-		assertEquals("admin", pp.getString("role"));
-//        assertEquals("de", pp.getString("language"));
-		assertEquals("html", pp.getString("media-type"));
-		assertEquals("Registerone.vm", pp.getString("template"));
-
-		TemplateURI uri2 = new TemplateURI(pipelineData.getRunData());
-		uri2.clearResponse();
-		uri2.setTemplate("Registerone.vm");
-		pp.remove("role");
-		pp.add("role", "anon");
-		uri2.addPathInfo(pp);
-
-		// this is an artifical url, as the exact sequence could not be reconstructed as
-		// ParameterParser uses expicitely a random access table
-		assertEquals(
-				"scheme://bob/wow/damn2/template/Registerone.vm/media-type/html/js_pane/random-id-123-abc/role/anon",
-				uri2.getAbsoluteLink());
-		urlMapper.mapToURL(uri2);
-		String expectedMappedURL = "/wow/register";
-		assertEquals(expectedMappedURL, uri2.getRelativeLink());
-
-		pp.clear();
-		pp.add("role", "admin");// will be overridden
-		urlMapper.mapFromURL("/app/contact", pp);
-		assertEquals(4, pp.keySet().size());
-		assertEquals("anon", pp.getString("role"));
-		assertEquals("another-random-id-876-dfg", pp.getString("js_pane"));
-
-		uri2 = new TemplateURI(pipelineData.getRunData());
-		uri2.clearResponse();
-		uri2.addPathInfo(pp);
-
-		// this is an artifical url
-		assertEquals("scheme://bob/wow/damn2/page/Contact/media-type/html/js_pane/another-random-id-876-dfg/role/anon",
-				uri2.getAbsoluteLink());
-		urlMapper.mapToURL(uri2);
-		expectedMappedURL = "/wow/contact";
-		assertEquals(expectedMappedURL, uri2.getRelativeLink());
+public class TurbineURLMapperYAMLServiceTest extends BaseTestCase
+{
+
+    private static TurbineConfig tc = null;
+
+    private static URLMapperService urlMapper = null;
+
+    private RunData data;
+
+    Logger log = LogManager.getLogger();
+
+    @BeforeAll
+    public static void setUp() throws Exception
+    {
+        tc = new TurbineConfig( ".", "/conf/test/TurbineURLMapperYAMLServiceTest.properties" );
+        tc.initialize();
+
+        urlMapper = (URLMapperService) TurbineServices.getInstance().getService( URLMapperService.SERVICE_NAME );
+    }
+
+    @AfterAll
+    public static void tearDown() throws Exception
+    {
+        if (tc != null)
+        {
+            tc.dispose();
+        }
+    }
+
+    @BeforeEach
+    public void init() throws Exception
+    {
+
+        ServletConfig config = tc.getTurbine().getServletConfig();
+        // mock(ServletConfig.class);
+        HttpServletRequest request = getMockRequest();
+        HttpServletResponse response = mock( HttpServletResponse.class );
+
+        data = getRunData( request, response, config );
+
+        Mockito.when( response.encodeURL( Mockito.anyString() ) )
+                .thenAnswer( invocation -> invocation.getArgument( 0 ) );
+    }
+
+    @Test
+    public void testMapToAnotherURL() throws Exception
+    {
+
+        PipelineData pipelineData = data;
+
+        assertNotNull( urlMapper );
+
+        TemplateURI uri = new TemplateURI( pipelineData.getRunData() );
+        uri.addPathInfo( "id", 1234 );
+        uri.addPathInfo( "role", "guest" );
+        uri.addPathInfo( "language", "de" );
+
+        String unMappedURL = uri.getAbsoluteLink(); // scheme://bob/wow/damn2/id/1234/role/guest
+        log.info( unMappedURL );
+
+        String expectedRawURL = "scheme://bob/wow/damn2/id/1234/role/guest/language/de";
+        urlMapper.mapToURL( uri );
+        urlMapper.mapToURL( uri ); // should be idempotent
+        // raw url
+        assertEquals( expectedRawURL, unMappedURL );
+
+        String mappedLink = uri.getRelativeLink(); // wow/damn2/id/1234/role/guest
+        log.info( mappedLink );
+        String expectedMappedURL = "/wow/1234/guest/de";
+        assertEquals( expectedMappedURL, mappedLink );
+
+        ParameterParser pp = pipelineData.get( Turbine.class, ParameterParser.class );
+        assertNotNull( pp );
+        assertTrue( pp.keySet().isEmpty() );
+        urlMapper.mapFromURL( mappedLink, pp );
+
+        assertEquals( 5, pp.keySet().size() );
+        assertEquals( 1234, pp.getInt( "id" ) );
+        assertEquals( "guest", pp.getString( "role" ) );
+        assertEquals( "de", pp.getString( "language" ) );
+        assertEquals( "html", pp.getString( "media-type" ) );
+
+        TemplateURI uri2 = new TemplateURI( pipelineData.getRunData() );
+        uri2.clearResponse();
+        uri2.setTemplate( "default.vm" );
+        uri2.addPathInfo( pp );
+        // this is an artifical url
+        assertEquals( "scheme://bob/wow/damn2/template/default.vm/media-type/html/role/guest/id/1234/language/de",
+                uri2.getAbsoluteLink() );
+        urlMapper.mapToURL( uri2 );
+        assertEquals( expectedMappedURL, uri2.getRelativeLink() );
+    }
+
+    @Test
+    public void testOverrideShortURL() throws Exception
+    {
+
+        PipelineData pipelineData = data;
+
+        assertNotNull( urlMapper );
+
+        ParameterParser pp = pipelineData.get( Turbine.class, ParameterParser.class );
+        assertNotNull( pp );
+        assertTrue( pp.keySet().isEmpty() );
+
+        pp.add( "role", "admin" ); // will not be overridden
+        urlMapper.mapFromURL( "/app/register", pp );
+
+        log.info( "parameters: {}", pp );
+        assertEquals( 4, pp.keySet().size() );
+        assertEquals( "random-id-123-abc", pp.getString( "js_pane" ) );
+        assertEquals( "admin", pp.getString( "role" ) );
+        assertEquals( "html", pp.getString( "media-type" ) );
+        assertEquals( "Registerone.vm", pp.getString( "template" ) );
+
+        TemplateURI uri2 = new TemplateURI( pipelineData.getRunData() );
+        uri2.clearResponse();
+        uri2.setTemplate( "Registerone.vm" );
+        pp.remove( "role" );
+        pp.add( "role", "anon" );
+        uri2.addPathInfo( pp );
+
+        // this is an artifical url, as the exact sequence could not be reconstructed as
+        // ParameterParser uses expicitely a random access table
+        assertEquals(
+                "scheme://bob/wow/damn2/template/Registerone.vm/media-type/html/js_pane/random-id-123-abc/role/anon",
+                uri2.getAbsoluteLink() );
+        urlMapper.mapToURL( uri2 );
+        String expectedMappedURL = "/wow/damn2/register";
+        assertEquals( expectedMappedURL, uri2.getRelativeLink() );
+
+        pp.clear();
+        pp.add( "role", "admin" );// will be overridden
+        urlMapper.mapFromURL( "/app/contact", pp );
+        log.info( "parameters: {}", pp );
+        assertEquals( 4, pp.keySet().size() );
+        assertEquals( "anon", pp.getString( "role" ) );
+        assertEquals( "another-random-id-876-dfg", pp.getString( "js_pane" ) );
+
+        uri2 = new TemplateURI( pipelineData.getRunData() );
+        uri2.clearResponse();
+        uri2.addPathInfo( pp );
+
+        // this is an artifical url
+        assertEquals( "scheme://bob/wow/damn2/page/Contact/media-type/html/js_pane/another-random-id-876-dfg/role/anon",
+                uri2.getAbsoluteLink() );
+        urlMapper.mapToURL( uri2 );
+        expectedMappedURL = "/wow/damn2/contact";
+        assertEquals( expectedMappedURL, uri2.getRelativeLink() );
+
+    }
 
-	}
-	
 //	/**
 //	 * 		Not implemented Test for MappedTemplateLink:
 //	 * - To work with <i>MappedTemplateLink</i>, we need access to the urlmapperservice in order to 

Modified: turbine/core/trunk/src/test/org/apache/turbine/services/urlmapper/model/YamlURLMappingContainerTest.java
URL: http://svn.apache.org/viewvc/turbine/core/trunk/src/test/org/apache/turbine/services/urlmapper/model/YamlURLMappingContainerTest.java?rev=1886168&r1=1886167&r2=1886168&view=diff
==============================================================================
--- turbine/core/trunk/src/test/org/apache/turbine/services/urlmapper/model/YamlURLMappingContainerTest.java (original)
+++ turbine/core/trunk/src/test/org/apache/turbine/services/urlmapper/model/YamlURLMappingContainerTest.java Wed Feb  3 15:42:22 2021
@@ -1,7 +1,9 @@
 package org.apache.turbine.services.urlmapper.model;
 
-
-import static org.junit.jupiter.api.Assertions.*;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertNotEquals;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertTrue;
 
 import java.io.FileInputStream;
 import java.io.InputStream;
@@ -24,43 +26,44 @@ public class YamlURLMappingContainerTest
     @BeforeAll
     public static void setUp() throws Exception
     {
-        try (InputStream reader = new FileInputStream("conf/turbine-url-mapping.yml"))
+        try (InputStream reader = new FileInputStream( "conf/turbine-url-mapping.yml" ))
         {
-        	ObjectMapper mapper = new ObjectMapper(new YAMLFactory());
-        	// List<URLMapEntry> urlList = 
-        	// mapper.readValue(reader, mapper.getTypeFactory().constructCollectionType(List.class, URLMapEntry.class));//            	
-        	container = mapper.readValue(reader, URLMappingContainer.class);
+            ObjectMapper mapper = new ObjectMapper( new YAMLFactory() );
+            // List<URLMapEntry> urlList =
+            // mapper.readValue(reader, mapper.getTypeFactory().constructCollectionType(List.class,
+            // URLMapEntry.class));//
+            container = mapper.readValue( reader, URLMappingContainer.class );
         }
     }
 
     @Test
     public void testGetName()
     {
-        assertNotNull(container);
-        assertEquals("default", container.getName());
+        assertNotNull( container );
+        assertEquals( "default", container.getName() );
     }
 
     @Test
     public void testGetMapEntries()
     {
-        assertNotNull(container);
+        assertNotNull( container );
 
         List<URLMapEntry> mapEntries = container.getMapEntries();
-        assertNotNull(mapEntries);
-        assertNotEquals(0, mapEntries.size());
+        assertNotNull( mapEntries );
+        assertNotEquals( 0, mapEntries.size() );
 
-        URLMapEntry entry = mapEntries.get(0);
-        assertNotNull(entry);
+        URLMapEntry entry = mapEntries.get( 0 );
+        assertNotNull( entry );
 
         Pattern pattern = entry.getUrlPattern();
-        assertNotNull(pattern);
-        assertTrue(pattern.matcher("/app/book/123").matches());
+        assertNotNull( pattern );
+        assertTrue( pattern.matcher( "/app/book/123" ).matches() );
 
         Map<String, String> implicit = entry.getImplicitParameters();
-        assertNotNull(implicit);
-        assertEquals(2, implicit.size());
-        assertEquals("Book.vm", implicit.get("template"));
-        assertEquals("0", implicit.get("detail"));
+        assertNotNull( implicit );
+        assertEquals( 2, implicit.size() );
+        assertEquals( "Book.vm", implicit.get( "template" ) );
+        assertEquals( "0", implicit.get( "detail" ) );
     }
 
 }

Added: 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=1886168&view=auto
==============================================================================
--- turbine/core/trunk/xdocs/howto/url-mapper-howto.xml (added)
+++ turbine/core/trunk/xdocs/howto/url-mapper-howto.xml Wed Feb  3 15:42:22 2021
@@ -0,0 +1,114 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements.  See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership.  The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License.  You may obtain a copy of the License at
+
+   http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied.  See the License for the
+ specific language governing permissions and limitations
+ under the License.
+-->
+
+<document>
+
+ <properties>
+  <title>URL Mapper Howto</title>
+ </properties>
+
+<body>
+
+<section>
+
+<p>
+Unaltered Turbine URLs 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>
+</p>
+
+
+</section>
+
+<section name="Turbine Configuration">
+
+<p>
+You need to register the URL Mapper service in the pipeline by adding the service, the configuration 
+</p>
+
+<p>
+In TurbineResources.properties, search URLMapperService, and if not found, add the following settings:
+</p>
+
+<source><![CDATA[
+
+# -------------------------------------------------------------------
+#
+#  U R L  M A P P E R  S E R V I C E
+#
+# -------------------------------------------------------------------
+
+# new mapper
+tool.request.mlink=org.apache.turbine.services.urlmapper.MappedTemplateLink
+
+services.URLMapperService.classname=org.apache.turbine.services.urlmapper.TurbineURLMapperService
+
+# xml, json and yml supported as extension
+services.URLMapperService.configFile = /conf/turbine-url-mapping.xml
+
+]]></source>
+
+<p>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>
+    ...
+
+]]></source>
+
+<p>This will read the beautfied URL and alter into to what, the server requires as defined 
+in the URLMapperService's configfile . 
+</p>
+
+<source><![CDATA[
+<url-mapping name="default">
+    <maps>
+        <map>
+            <pattern>/(?&lt;contextPath&gt;\w+)/book/(?&lt;bookId&gt;\d+)</pattern>
+            <implicit-parameters>
+                <parameter key="template">Book.vm</parameter>
+                <parameter key="detail">0</parameter>
+            </implicit-parameters>
+        </map>
+        ...
+]]></source>
+
+<p>
+Use it in the templates, e.g.
+</p>
+
+<source><![CDATA[
+    $mlink.addPathInfo("world","nice").getRelativeLink()
+    ## may result into /beautiful/world
+]]></source>
+
+<p>
+More examples ...
+</p>
+
+
+</section>
+
+</body>
+</document>