Author: pete
Date: Wed Dec  8 00:43:49 2010
New Revision: 1043244

URL: http://svn.apache.org/viewvc?rev=1043244&view=rev
Log:
in ResourceMapper, utilize AbstractMapper methods for page parameter and url 
handling:

- behave similar to MountedMapper
- as a side effect this will now support placeholders in the mount segment 
- more test cases
- custom parameter encoder

Modified:
    
wicket/trunk/wicket-request/src/main/java/org/apache/wicket/request/mapper/AbstractMapper.java
    
wicket/trunk/wicket/src/main/java/org/apache/wicket/request/mapper/ResourceMapper.java
    
wicket/trunk/wicket/src/test/java/org/apache/wicket/request/mapper/ResourceMapperTest.java

Modified: 
wicket/trunk/wicket-request/src/main/java/org/apache/wicket/request/mapper/AbstractMapper.java
URL: 
http://svn.apache.org/viewvc/wicket/trunk/wicket-request/src/main/java/org/apache/wicket/request/mapper/AbstractMapper.java?rev=1043244&r1=1043243&r2=1043244&view=diff
==============================================================================
--- 
wicket/trunk/wicket-request/src/main/java/org/apache/wicket/request/mapper/AbstractMapper.java
 (original)
+++ 
wicket/trunk/wicket-request/src/main/java/org/apache/wicket/request/mapper/AbstractMapper.java
 Wed Dec  8 00:43:49 2010
@@ -123,8 +123,7 @@ public abstract class AbstractMapper imp
                        removeMetaParameter(urlCopy);
                }
 
-               PageParameters decoded = 
encoder.decodePageParameters(request.cloneWithUrl(urlCopy));
-               return decoded;
+               return 
encoder.decodePageParameters(request.cloneWithUrl(urlCopy));
        }
 
        /**

Modified: 
wicket/trunk/wicket/src/main/java/org/apache/wicket/request/mapper/ResourceMapper.java
URL: 
http://svn.apache.org/viewvc/wicket/trunk/wicket/src/main/java/org/apache/wicket/request/mapper/ResourceMapper.java?rev=1043244&r1=1043243&r2=1043244&view=diff
==============================================================================
--- 
wicket/trunk/wicket/src/main/java/org/apache/wicket/request/mapper/ResourceMapper.java
 (original)
+++ 
wicket/trunk/wicket/src/main/java/org/apache/wicket/request/mapper/ResourceMapper.java
 Wed Dec  8 00:43:49 2010
@@ -16,17 +16,14 @@
  */
 package org.apache.wicket.request.mapper;
 
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Iterator;
-import java.util.List;
-
 import org.apache.wicket.request.IRequestHandler;
 import org.apache.wicket.request.IRequestMapper;
 import org.apache.wicket.request.Request;
 import org.apache.wicket.request.Url;
 import 
org.apache.wicket.request.handler.resource.ResourceReferenceRequestHandler;
+import org.apache.wicket.request.mapper.parameter.IPageParametersEncoder;
 import org.apache.wicket.request.mapper.parameter.PageParameters;
+import org.apache.wicket.request.mapper.parameter.PageParametersEncoder;
 import org.apache.wicket.request.resource.ResourceReference;
 import org.apache.wicket.util.lang.Args;
 
@@ -34,13 +31,13 @@ import org.apache.wicket.util.lang.Args;
  * mapper to mount resources to a custom mount path
  * <ul>
  * <li>maps indexed parameters to path segments</li>
- * <li>maps named parameters to query string arguments</li>
+ * <li>maps named parameters to query string arguments or placeholder path 
segments</li>
  * </ul>
  * 
- * <h4>sample structure of url</h4>
- * 
+ * <strong>sample structure of url</strong>
+ *
  * <pre>
- *    
/articles/images/[indexed-param-0]/[indexed-param-1]?[named-param-1=value]&[named-param-2=value2]
+ *    
/resources/${category}/images/[indexed-param-0]/[indexed-param-1]?[named-param-1=value]&[named-param-2=value2]
  * </pre>
  * 
  * <h4>sample usage</h4>
@@ -51,11 +48,16 @@ import org.apache.wicket.util.lang.Args;
  * <pre>
  * getRootRequestMapperAsCompound().add(new 
ResourceMapper(&quot;/images&quot;, new ImagesResourceReference()));
  * </pre>
- * 
+ *
+ * @see 
org.apache.wicket.protocol.http.WebApplication#mountSharedResource(String, 
org.apache.wicket.request.resource.ResourceReference)
+ *
  * @author Peter Ertl
  */
 public class ResourceMapper extends AbstractMapper implements IRequestMapper
 {
+       // encode parameters into url, decode parameters from url
+       private final IPageParametersEncoder parametersEncoder;
+
        // path the resource is bound to
        private final String[] mountSegments;
 
@@ -75,7 +77,28 @@ public class ResourceMapper extends Abst
                Args.notEmpty(path, "path");
                Args.notNull(resourceReference, "resourceReference");
                this.resourceReference = resourceReference;
-               mountSegments = getMountSegments(path);
+               this.mountSegments = getMountSegments(path);
+               this.parametersEncoder = new PageParametersEncoder();
+       }
+
+       /**
+        * create a resource mapper for a resource
+        *
+        * @param path
+        *            mount path for the resource
+        * @param resourceReference
+        *            resource reference that should be linked to the mount path
+        * @param encoder
+        *            encoder for url parameters
+        */
+       public ResourceMapper(String path, ResourceReference resourceReference, 
IPageParametersEncoder encoder)
+       {
+               Args.notEmpty(path, "path");
+               Args.notNull(resourceReference, "resourceReference");
+               Args.notNull(encoder, "encoder");
+               this.resourceReference = resourceReference;
+               this.mountSegments = getMountSegments(path);
+               this.parametersEncoder = encoder;
        }
 
        /**
@@ -83,31 +106,30 @@ public class ResourceMapper extends Abst
         */
        public IRequestHandler mapRequest(final Request request)
        {
-               Url url = request.getUrl();
-               Iterator<String> segments = url.getSegments().iterator();
+               final Url url = request.getUrl();
 
-               // see if url matches the path we are mounted at
-               for (String mountSegment : mountSegments)
-               {
-                       if (segments.hasNext() == false)
-                               return null; // given url is too short
-
-                       if (mountSegment.equals(segments.next()) == false)
-                               return null; // url does not fully match
-               }
+               // check if url matches mount path
+               if (urlStartsWith(url, mountSegments) == false)
+                       return null;
 
                // now extract the page parameters from the request url
-               PageParameters parameters = new PageParameters();
+               PageParameters parameters = extractPageParameters(request, 
mountSegments.length, parametersEncoder);
 
-               // extract indexed parameters
-               int index = 0;
-               while (segments.hasNext())
-                       parameters.set(index++, segments.next());
-
-               // extract named parameters
-               for (Url.QueryParameter queryParameter : 
url.getQueryParameters())
-                       parameters.add(queryParameter.getName(), 
queryParameter.getValue());
+               // check if there are placeholders in mount segments
+               for (int i = 0; i < mountSegments.length; ++i)
+               {
+                       String placeholder = getPlaceholder(mountSegments[i]);
 
+                       if (placeholder != null)
+                       {
+                               // extract the parameter from URL
+                               if (parameters == null)
+                               {
+                                       parameters = new PageParameters();
+                               }
+                               parameters.add(placeholder, 
url.getSegments().get(i));
+                       }
+               }
                return new ResourceReferenceRequestHandler(resourceReference, 
parameters);
        }
 
@@ -133,29 +155,29 @@ public class ResourceMapper extends Abst
                if 
(resourceReference.getResource().equals(handler.getResource()) == false)
                        return null;
 
-               // create path to resource
-               List<String> path = new ArrayList<String>();
+               Url url = new Url();
 
-               // add mount segments
-               path.addAll(Arrays.asList(mountSegments));
+               // add mount path segments
+               for (String segment : mountSegments)
+               {
+                       url.getSegments().add(segment);
+               }
 
-               // next we add the page parameters to the resulting path
-               PageParameters parameters = handler.getPageParameters();
+               // replace placeholder parameters
+               PageParameters parameters = new 
PageParameters(handler.getPageParameters());
 
-               // append indexed parameters as path segments
-               for (int index = 0; index < parameters.getIndexedCount(); 
index++)
-                       path.add(parameters.get(index).toString());
-
-               // append named parameters as query strings
-               List<PageParameters.NamedPair> namedParameters = 
parameters.getAllNamed();
-               List<Url.QueryParameter> queryParams = new 
ArrayList<Url.QueryParameter>(
-                       namedParameters.size());
-
-               for (PageParameters.NamedPair namedParameter : namedParameters)
-                       queryParams.add(new 
Url.QueryParameter(namedParameter.getKey(),
-                               namedParameter.getValue()));
+               for (int i = 0; i < mountSegments.length; ++i)
+               {
+                       String placeholder = getPlaceholder(mountSegments[i]);
+
+                       if (placeholder != null)
+                       {
+                               url.getSegments().set(i, 
parameters.get(placeholder).toString(""));
+                               parameters.remove(placeholder);
+                       }
+               }
 
-               // create and return url
-               return new Url(path, queryParams);
+               // create url
+               return encodePageParameters(url, parameters, parametersEncoder);
        }
 }

Modified: 
wicket/trunk/wicket/src/test/java/org/apache/wicket/request/mapper/ResourceMapperTest.java
URL: 
http://svn.apache.org/viewvc/wicket/trunk/wicket/src/test/java/org/apache/wicket/request/mapper/ResourceMapperTest.java?rev=1043244&r1=1043243&r2=1043244&view=diff
==============================================================================
--- 
wicket/trunk/wicket/src/test/java/org/apache/wicket/request/mapper/ResourceMapperTest.java
 (original)
+++ 
wicket/trunk/wicket/src/test/java/org/apache/wicket/request/mapper/ResourceMapperTest.java
 Wed Dec  8 00:43:49 2010
@@ -39,6 +39,7 @@ public class ResourceMapperTest extends 
        private static final String SHARED_NAME = "test-resource";
 
        private IRequestMapper mapper;
+       private IRequestMapper mapperWithPlaceholder;
        private TestResource resource;
 
        @Override
@@ -50,6 +51,7 @@ public class ResourceMapperTest extends 
                tester.getApplication().getSharedResources().add(SHARED_NAME, 
resource);
                ResourceReference resourceReference = new 
SharedResourceReference(SHARED_NAME);
                mapper = new ResourceMapper("/test/resource", 
resourceReference);
+               mapperWithPlaceholder = new 
ResourceMapper("/test2/${name}/resource", resourceReference);
                
tester.getApplication().getRootRequestMapperAsCompound().add(mapper);
        }
 
@@ -160,6 +162,62 @@ public class ResourceMapperTest extends 
                assertEquals(12, paramValue.toInt());
        }
 
+       @Test
+       public void testPlaceholders()
+       {
+               Request request = 
createRequest("test2/image/resource/foo/bar?a=abc&b=123");
+               IRequestHandler requestHandler = 
mapperWithPlaceholder.mapRequest(request);
+               assertNotNull(requestHandler);
+               assertEquals(ResourceReferenceRequestHandler.class, 
requestHandler.getClass());
+               assertEquals(request.getUrl(), 
mapperWithPlaceholder.mapHandler(requestHandler));
+
+               tester.processRequest(requestHandler);
+               PageParameters params = resource.pageParameters;
+               assertNotNull(params);
+               assertEquals(3, params.getAllNamed().size());
+               assertEquals(2, params.getIndexedCount());
+
+               assertEquals("foo", params.get(0).toString());
+               assertEquals("bar", params.get(1).toString());
+
+               assertEquals("image", params.get("name").toString());
+               assertEquals("abc", params.get("a").toString());
+               assertEquals("123", params.get("b").toString());
+       }
+
+       @Test
+       public void testPlaceholdersWithQueryParamDuplicate()
+       {
+               // we have one named parameter that exists twice
+               Request request = 
createRequest("test2/image/resource/foo/bar?name=name-2&val=123");
+               IRequestHandler handler = 
mapperWithPlaceholder.mapRequest(request);
+               assertNotNull(handler);
+               assertEquals(ResourceReferenceRequestHandler.class, 
handler.getClass());
+
+               // the query part of the duplicate should be gone now
+               Url newUrl = mapperWithPlaceholder.mapHandler(handler);
+               
assertEquals(Url.parse("test2/name-2/resource/foo/bar?val=123"), newUrl);
+
+               // create new request
+               request = createRequest(newUrl.toString());
+
+               // get handler again
+               handler = mapperWithPlaceholder.mapRequest(request);
+               assertNotNull(handler);
+
+               tester.processRequest(handler);
+               PageParameters params = resource.pageParameters;
+               assertNotNull(params);
+               assertEquals(2, params.getAllNamed().size());
+               assertEquals(2, params.getIndexedCount());
+
+               assertEquals("foo", params.get(0).toString());
+               assertEquals("bar", params.get(1).toString());
+
+               assertEquals("name-2", params.get("name").toString());
+               assertEquals("123", params.get("val").toString());
+       }
+
        private static class TestResource implements IResource
        {
                private static final long serialVersionUID = 
-3130204487473856574L;


Reply via email to