WICKET-6094 Find adequate ResourceReference with mount parameters

Project: http://git-wip-us.apache.org/repos/asf/wicket/repo
Commit: http://git-wip-us.apache.org/repos/asf/wicket/commit/d0b83efb
Tree: http://git-wip-us.apache.org/repos/asf/wicket/tree/d0b83efb
Diff: http://git-wip-us.apache.org/repos/asf/wicket/diff/d0b83efb

Branch: refs/heads/lambdas
Commit: d0b83efb22997664f797ff5f1fcb7c29e852d952
Parents: ed7c997
Author: Martin Tzvetanov Grigorov <[email protected]>
Authored: Thu Feb 18 22:52:06 2016 +0100
Committer: Martin Tzvetanov Grigorov <[email protected]>
Committed: Thu Feb 18 22:53:05 2016 +0100

----------------------------------------------------------------------
 .../mapper/AbstractBookmarkableMapper.java      |   3 -
 .../core/request/mapper/ResourceMapper.java     |  32 +++-
 .../MoreSpecificResourceMountPathTest.java      | 173 +++++++++++++++++++
 .../wicket/request/mapper/AbstractMapper.java   |  16 +-
 4 files changed, 211 insertions(+), 13 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/wicket/blob/d0b83efb/wicket-core/src/main/java/org/apache/wicket/core/request/mapper/AbstractBookmarkableMapper.java
----------------------------------------------------------------------
diff --git 
a/wicket-core/src/main/java/org/apache/wicket/core/request/mapper/AbstractBookmarkableMapper.java
 
b/wicket-core/src/main/java/org/apache/wicket/core/request/mapper/AbstractBookmarkableMapper.java
index 420b808..4d34e8c 100644
--- 
a/wicket-core/src/main/java/org/apache/wicket/core/request/mapper/AbstractBookmarkableMapper.java
+++ 
b/wicket-core/src/main/java/org/apache/wicket/core/request/mapper/AbstractBookmarkableMapper.java
@@ -201,9 +201,6 @@ public abstract class AbstractBookmarkableMapper extends 
AbstractComponentMapper
         */
        protected abstract boolean pageMustHaveBeenCreatedBookmarkable();
 
-       /**
-        * @see IRequestMapper#getCompatibilityScore(Request)
-        */
        @Override
        public int getCompatibilityScore(Request request)
        {

http://git-wip-us.apache.org/repos/asf/wicket/blob/d0b83efb/wicket-core/src/main/java/org/apache/wicket/core/request/mapper/ResourceMapper.java
----------------------------------------------------------------------
diff --git 
a/wicket-core/src/main/java/org/apache/wicket/core/request/mapper/ResourceMapper.java
 
b/wicket-core/src/main/java/org/apache/wicket/core/request/mapper/ResourceMapper.java
index c438319..d89543e 100644
--- 
a/wicket-core/src/main/java/org/apache/wicket/core/request/mapper/ResourceMapper.java
+++ 
b/wicket-core/src/main/java/org/apache/wicket/core/request/mapper/ResourceMapper.java
@@ -27,7 +27,6 @@ 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.http.flow.AbortWithHttpErrorCodeException;
-import org.apache.wicket.request.mapper.AbstractMapper;
 import org.apache.wicket.request.mapper.parameter.INamedParameters;
 import org.apache.wicket.request.mapper.parameter.IPageParametersEncoder;
 import org.apache.wicket.request.mapper.parameter.PageParameters;
@@ -71,7 +70,7 @@ import org.apache.wicket.util.string.Strings;
  *
  * @author Peter Ertl
  */
-public class ResourceMapper extends AbstractMapper implements IRequestMapper
+public class ResourceMapper extends AbstractBookmarkableMapper
 {
        // encode page parameters into url + decode page parameters from url
        private final IPageParametersEncoder parametersEncoder;
@@ -111,9 +110,8 @@ public class ResourceMapper extends AbstractMapper 
implements IRequestMapper
        public ResourceMapper(String path, ResourceReference resourceReference,
                IPageParametersEncoder encoder)
        {
-               Args.notEmpty(path, "path");
+               super(path, encoder);
                Args.notNull(resourceReference, "resourceReference");
-               Args.notNull(encoder, "encoder");
 
                this.resourceReference = resourceReference;
                mountSegments = getMountSegments(path);
@@ -157,9 +155,33 @@ public class ResourceMapper extends AbstractMapper 
implements IRequestMapper
        }
 
        @Override
+       protected final UrlInfo parseRequest(final Request request) {
+               throw new UnsupportedOperationException();
+       }
+
+       @Override
+       protected final Url buildUrl(final UrlInfo info) {
+               throw new UnsupportedOperationException();
+       }
+
+       @Override
+       protected final boolean pageMustHaveBeenCreatedBookmarkable() {
+               throw new UnsupportedOperationException();
+       }
+
+       @Override
        public int getCompatibilityScore(Request request)
        {
-               return 0; // pages always have priority over resources
+               int score = super.getCompatibilityScore(request);
+               if (score > 0)
+               {
+                       score--; // pages always have priority over resources
+               }
+               else
+               {
+                       score = -1;
+               }
+               return score;
        }
 
        @Override

http://git-wip-us.apache.org/repos/asf/wicket/blob/d0b83efb/wicket-core/src/test/java/org/apache/wicket/core/request/mapper/MoreSpecificResourceMountPathTest.java
----------------------------------------------------------------------
diff --git 
a/wicket-core/src/test/java/org/apache/wicket/core/request/mapper/MoreSpecificResourceMountPathTest.java
 
b/wicket-core/src/test/java/org/apache/wicket/core/request/mapper/MoreSpecificResourceMountPathTest.java
new file mode 100644
index 0000000..9d5f582
--- /dev/null
+++ 
b/wicket-core/src/test/java/org/apache/wicket/core/request/mapper/MoreSpecificResourceMountPathTest.java
@@ -0,0 +1,173 @@
+/*
+ * 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.
+ */
+package org.apache.wicket.core.request.mapper;
+
+import org.apache.wicket.Application;
+import org.apache.wicket.markup.html.WebPage;
+import org.apache.wicket.protocol.http.WebApplication;
+import org.apache.wicket.request.cycle.RequestCycle;
+import org.apache.wicket.request.mapper.parameter.PageParameters;
+import org.apache.wicket.request.resource.ByteArrayResource;
+import org.apache.wicket.request.resource.IResource;
+import org.apache.wicket.request.resource.ResourceReference;
+import org.apache.wicket.util.string.StringValue;
+import org.apache.wicket.util.tester.DummyHomePage;
+import org.apache.wicket.util.tester.WicketTester;
+import org.junit.Assert;
+import org.junit.Test;
+
+import java.net.URL;
+
+import static org.hamcrest.CoreMatchers.equalTo;
+import static org.hamcrest.CoreMatchers.is;
+
+/**
+ * https://issues.apache.org/jira/browse/WICKET-6094
+ */
+public class MoreSpecificResourceMountPathTest
+{
+       @Test
+       public void can_use_resource_mounted_without_parameter() 
+       {
+               WicketTester browser = new WicketTester(new 
WicketApplication());
+               browser.executeUrl(WicketApplication.urlFor("howdy"));
+               Assert.assertThat(browser.getLastResponseAsString(), 
is(equalTo("howdy")));
+       }
+
+       @Test
+       public void can_use_resource_mounted_with_parameter() 
+       {
+               WicketTester browser = new WicketTester(new 
WicketApplication());
+               browser.executeUrl(WicketApplication.urlFor(1L));
+               Assert.assertThat(browser.getLastResponseAsString(), 
is(equalTo("1")));
+       }
+
+       public static class WicketApplication extends WebApplication 
+       {
+               private static final String OWNER_BY_ID_LOADER = 
"owner-by-id-loader";
+               private static final String OWNERS_LISTER = "owners-lister";
+               public static final String PARAM_ID = "id";
+               public static final String PARAM_NAME = "name";
+
+               @Override
+               public Class<? extends WebPage> getHomePage() 
+               {
+                       return DummyHomePage.class;
+               }
+
+               @Override
+               public void init() 
+               {
+                       super.init();
+
+                       String path = "/ajax/owners"; // shared by both 
references
+                       
+                       mountResource(path, new 
ResourceReference(OWNERS_LISTER) 
+                       {
+                               @Override
+                               public IResource getResource() 
+                               {
+                                       return new DummyResource(PARAM_NAME);
+                               }
+                       });
+
+                       mountResource(path + "/${" + PARAM_ID + "}", new 
ResourceReference(OWNER_BY_ID_LOADER) 
+                       {
+                               @Override
+                               public IResource getResource() 
+                               {
+                                       return new DummyResource(PARAM_ID);
+                               }
+                       });
+               }
+
+               public static String urlFor(String name) 
+               {
+                       return urlFor(name, PARAM_NAME, OWNERS_LISTER);
+               }
+
+               public static String urlFor(Long id) 
+               {
+                       return urlFor(id, PARAM_ID, OWNER_BY_ID_LOADER);
+               }
+
+               /** <Test-Helper>
+                * Generate an {@link URL} to access the mounted resource 
reference.
+                * @param value of dummy attribute used to have some testable 
response output.
+                * @param parameterName of dummy attribute
+                * @param resourceReferenceName used to mount instance
+                * @return {@link CharSequence} url for resource reference
+                */
+               private static String urlFor(Object value, String 
parameterName, String resourceReferenceName) 
+               {
+                       PageParameters parameters = new PageParameters();
+                       if (value != null) 
+                       {
+                               parameters.set(parameterName, value);
+                       }
+                       ResourceReference resourceReference = 
findResourceReference(resourceReferenceName);
+                       String string = 
RequestCycle.get().urlFor(resourceReference, parameters).toString();
+                       return string;
+               }
+
+               /** <Test-Helper>
+                * Find resource reference mounted in application.
+                * @param name of resource reference used to mount instance
+                * @return {@link ResourceReference} found
+                */
+               private static ResourceReference findResourceReference(String 
name) 
+               {
+                       return Application.get()
+                                       .getResourceReferenceRegistry()
+                                       .getResourceReference(
+                                                       new 
ResourceReference.Key(
+                                                                       
Application.class.getName(),
+                                                                       name,
+                                                                       null,
+                                                                       null,
+                                                                       null
+                                                       ),
+                                                       false,
+                                                       false
+                                       );
+               }
+
+               /** <Test-Helper>
+                * This is only a dummy to be referenced. It is possible to
+                * exchange this by a mock or whatever.
+                * 
+                * @author [email protected]
+                */
+               private static class DummyResource extends ByteArrayResource 
+               {
+                       private final String parameterName;
+
+                       public DummyResource(String parameterName) 
+                       {
+                               super("application/text");
+                               this.parameterName = parameterName;
+                       }
+
+                       @Override
+                       protected byte[] getData(Attributes attributes) 
+                       {
+                               StringValue value = 
attributes.getParameters().get(parameterName);
+                               return value == null ? new byte[0] : 
value.toString().getBytes();
+                       }
+               }
+       }
+}

http://git-wip-us.apache.org/repos/asf/wicket/blob/d0b83efb/wicket-request/src/main/java/org/apache/wicket/request/mapper/AbstractMapper.java
----------------------------------------------------------------------
diff --git 
a/wicket-request/src/main/java/org/apache/wicket/request/mapper/AbstractMapper.java
 
b/wicket-request/src/main/java/org/apache/wicket/request/mapper/AbstractMapper.java
index 5f5060b..a9f7143 100644
--- 
a/wicket-request/src/main/java/org/apache/wicket/request/mapper/AbstractMapper.java
+++ 
b/wicket-request/src/main/java/org/apache/wicket/request/mapper/AbstractMapper.java
@@ -86,8 +86,7 @@ public abstract class AbstractMapper implements IRequestMapper
        }
 
        /**
-        * Returns true if the given url starts with specified segments. 
Segments that contain
-        * placeholders are not compared.
+        * Returns true if the given url starts with specified segments.
         * 
         * @param url
         * @param segments
@@ -105,9 +104,16 @@ public abstract class AbstractMapper implements 
IRequestMapper
                
                for (int i = 0; i < segments.length; ++i)
                {
-                       if (!segments[i].equals(safeSegmentGetter(urlSegments, 
i , "")) &&
-                               (getPlaceholder(segments[i]) == null && 
-                                getOptionalPlaceholder(segments[i]) == null))
+                       String segment = segments[i];
+                       String urlSegment = safeSegmentGetter(urlSegments, i, 
null);
+                       if (urlSegment == null && 
getOptionalPlaceholder(segment) == null)
+                       {
+                               // if the 'segment' has static value or is 
mandatory placeholder
+                               return false;
+                       }
+                       else if (!segment.equals(urlSegment) &&
+                           (getPlaceholder(segment) == null &&
+                            getOptionalPlaceholder(segment) == null))
                        {
                                return false;
                        }

Reply via email to