- 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
git-svn-id: https://svn.apache.org/repos/asf/turbine/core/trunk@1886168 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/conf/test/TorqueTest.properties b/conf/test/TorqueTest.properties
index 7cfcd5f..d04f0f1 100644
--- a/conf/test/TorqueTest.properties
+++ b/conf/test/TorqueTest.properties
@@ -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 @@
# 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:.
diff --git a/conf/test/TurbineURLMapperServiceTest.properties b/conf/test/TurbineURLMapperServiceTest.properties
index 53a36d3..0a7c791 100644
--- a/conf/test/TurbineURLMapperServiceTest.properties
+++ b/conf/test/TurbineURLMapperServiceTest.properties
@@ -127,7 +127,24 @@
# -------------------------------------------------------------------
#
+# 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
diff --git a/conf/test/TurbineURLMapperYAMLServiceTest.properties b/conf/test/TurbineURLMapperYAMLServiceTest.properties
new file mode 100644
index 0000000..8865dae
--- /dev/null
+++ b/conf/test/TurbineURLMapperYAMLServiceTest.properties
@@ -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
+
diff --git a/conf/turbine-url-mapping.json b/conf/turbine-url-mapping.json
new file mode 100644
index 0000000..731a75b
--- /dev/null
+++ b/conf/turbine-url-mapping.json
@@ -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
diff --git a/conf/turbine-url-mapping.yml b/conf/turbine-url-mapping.yml
index 6a47d64..d3f1781 100644
--- a/conf/turbine-url-mapping.yml
+++ b/conf/turbine-url-mapping.yml
@@ -1,4 +1,3 @@
-
name: default
maps:
- pattern: /(?<contextPath>\w+)/book/(?<bookId>\d+)
@@ -10,22 +9,22 @@
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
diff --git a/pom.xml b/pom.xml
index 6aa42d7..08796ed 100644
--- a/pom.xml
+++ b/pom.xml
@@ -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>
diff --git a/src/java/org/apache/turbine/services/urlmapper/TurbineURLMapperService.java b/src/java/org/apache/turbine/services/urlmapper/TurbineURLMapperService.java
index dc79c2f..941b29b 100644
--- a/src/java/org/apache/turbine/services/urlmapper/TurbineURLMapperService.java
+++ b/src/java/org/apache/turbine/services/urlmapper/TurbineURLMapperService.java
@@ -182,18 +182,21 @@
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 @@
// 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)
diff --git a/src/test/org/apache/turbine/services/urlmapper/TurbineURLMapperJSONServiceTest.java b/src/test/org/apache/turbine/services/urlmapper/TurbineURLMapperJSONServiceTest.java
new file mode 100644
index 0000000..e5be01f
--- /dev/null
+++ b/src/test/org/apache/turbine/services/urlmapper/TurbineURLMapperJSONServiceTest.java
@@ -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() );
+
+ }
+
+}
diff --git a/src/test/org/apache/turbine/services/urlmapper/TurbineURLMapperYAMLServiceTest.java b/src/test/org/apache/turbine/services/urlmapper/TurbineURLMapperYAMLServiceTest.java
new file mode 100644
index 0000000..79c553a
--- /dev/null
+++ b/src/test/org/apache/turbine/services/urlmapper/TurbineURLMapperYAMLServiceTest.java
@@ -0,0 +1,213 @@
+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.Tag;
+import org.junit.jupiter.api.Test;
+import org.mockito.Mockito;
+
+@Tag("yaml")
+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
+// * - simulate a request without pipeline (setting velocity context and initializing the service):
+// */
+// @Test
+// public void testMappedURILink() {
+// MappedTemplateLink ml = MappedTemplateLink.class.getDeclaredConstructor().newInstance();
+// assertNotNull(ml);
+// ml.setUrlMapperService(urlMapper);
+// ml.init(data);
+// }
+
+}
diff --git a/src/test/org/apache/turbine/services/urlmapper/TurbineYamlURLMapperServiceTest.java b/src/test/org/apache/turbine/services/urlmapper/TurbineYamlURLMapperServiceTest.java
deleted file mode 100644
index b5bdc7a..0000000
--- a/src/test/org/apache/turbine/services/urlmapper/TurbineYamlURLMapperServiceTest.java
+++ /dev/null
@@ -1,206 +0,0 @@
-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.Assert.assertEquals;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.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.Tag;
-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());
-
- }
-
-// /**
-// * Not implemented Test for MappedTemplateLink:
-// * - To work with <i>MappedTemplateLink</i>, we need access to the urlmapperservice in order to
-// * - simulate a request without pipeline (setting velocity context and initializing the service):
-// */
-// @Test
-// public void testMappedURILink() {
-// MappedTemplateLink ml = MappedTemplateLink.class.getDeclaredConstructor().newInstance();
-// assertNotNull(ml);
-// ml.setUrlMapperService(urlMapper);
-// ml.init(data);
-// }
-
-}
diff --git a/src/test/org/apache/turbine/services/urlmapper/model/YamlURLMappingContainerTest.java b/src/test/org/apache/turbine/services/urlmapper/model/YamlURLMappingContainerTest.java
index b35f310..89d4922 100644
--- a/src/test/org/apache/turbine/services/urlmapper/model/YamlURLMappingContainerTest.java
+++ b/src/test/org/apache/turbine/services/urlmapper/model/YamlURLMappingContainerTest.java
@@ -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 @@
@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" ) );
}
}
diff --git a/xdocs/howto/url-mapper-howto.xml b/xdocs/howto/url-mapper-howto.xml
new file mode 100644
index 0000000..61ac402
--- /dev/null
+++ b/xdocs/howto/url-mapper-howto.xml
@@ -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>/(?<contextPath>\w+)/book/(?<bookId>\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>