diff --git a/src/main/java/org/springframework/hateoas/core/LinkBuilderSupport.java b/src/main/java/org/springframework/hateoas/core/LinkBuilderSupport.java index dd62773d..ec30bec3 100644 --- a/src/main/java/org/springframework/hateoas/core/LinkBuilderSupport.java +++ b/src/main/java/org/springframework/hateoas/core/LinkBuilderSupport.java @@ -15,6 +15,8 @@ */ package org.springframework.hateoas.core; +import static org.springframework.web.util.UriComponentsBuilder.*; + import java.net.URI; import org.springframework.hateoas.Identifiable; @@ -30,6 +32,7 @@ import org.springframework.web.util.UriComponentsBuilder; * * @author Ricardo Gladwell * @author Oliver Gierke + * @author Kamill Sokol */ public abstract class LinkBuilderSupport implements LinkBuilder { @@ -70,8 +73,11 @@ public abstract class LinkBuilderSupport implements LinkB return getThis(); } + String uriString = uriComponents.toUriString(); + UriComponentsBuilder builder = uriString.isEmpty() ? fromUri(uriComponents.toUri()) + : fromUriString(uriString); + UriComponents components = UriComponentsBuilder.fromUriString(path).build(); - UriComponentsBuilder builder = UriComponentsBuilder.fromUri(uriComponents.toUri()); for (String pathSegment : components.getPathSegments()) { builder.pathSegment(pathSegment); diff --git a/src/main/java/org/springframework/hateoas/jaxrs/JaxRsLinkBuilder.java b/src/main/java/org/springframework/hateoas/jaxrs/JaxRsLinkBuilder.java index a6d51992..d9adab63 100644 --- a/src/main/java/org/springframework/hateoas/jaxrs/JaxRsLinkBuilder.java +++ b/src/main/java/org/springframework/hateoas/jaxrs/JaxRsLinkBuilder.java @@ -1,5 +1,5 @@ /* - * Copyright 2012 the original author or authors. + * Copyright 2012-2014 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -22,13 +22,14 @@ import org.springframework.hateoas.core.AnnotationMappingDiscoverer; import org.springframework.hateoas.core.LinkBuilderSupport; import org.springframework.hateoas.core.MappingDiscoverer; import org.springframework.web.servlet.support.ServletUriComponentsBuilder; +import org.springframework.web.util.UriComponents; import org.springframework.web.util.UriComponentsBuilder; -import org.springframework.web.util.UriTemplate; /** * {@link LinkBuilder} to derive URI mappings from a JAX-RS {@link Path} annotation. * * @author Oliver Gierke + * @author Kamill Sokol */ public class JaxRsLinkBuilder extends LinkBuilderSupport { @@ -66,8 +67,9 @@ public class JaxRsLinkBuilder extends LinkBuilderSupport { JaxRsLinkBuilder builder = new JaxRsLinkBuilder(ServletUriComponentsBuilder.fromCurrentServletMapping()); - UriTemplate template = new UriTemplate(DISCOVERER.getMapping(service)); - return builder.slash(template.expand(parameters)); + UriComponents uriComponents = UriComponentsBuilder.fromUriString(DISCOVERER.getMapping(service)).build(); + UriComponents expandedComponents = uriComponents.expand(parameters); + return builder.slash(expandedComponents); } /* diff --git a/src/main/java/org/springframework/hateoas/mvc/ControllerLinkBuilder.java b/src/main/java/org/springframework/hateoas/mvc/ControllerLinkBuilder.java index 9e74e3d7..d36f3f4d 100755 --- a/src/main/java/org/springframework/hateoas/mvc/ControllerLinkBuilder.java +++ b/src/main/java/org/springframework/hateoas/mvc/ControllerLinkBuilder.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2013 the original author or authors. + * Copyright 2012-2014 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -32,6 +32,7 @@ import org.springframework.web.context.request.RequestAttributes; import org.springframework.web.context.request.RequestContextHolder; import org.springframework.web.context.request.ServletRequestAttributes; import org.springframework.web.servlet.support.ServletUriComponentsBuilder; +import org.springframework.web.util.UriComponents; import org.springframework.web.util.UriComponentsBuilder; import org.springframework.web.util.UriTemplate; @@ -39,6 +40,7 @@ import org.springframework.web.util.UriTemplate; * Builder to ease building {@link Link} instances pointing to Spring MVC controllers. * * @author Oliver Gierke + * @author Kamill Sokol */ public class ControllerLinkBuilder extends LinkBuilderSupport { @@ -79,9 +81,11 @@ public class ControllerLinkBuilder extends LinkBuilderSupport { @@ -133,7 +134,7 @@ public class ControllerLinkBuilderFactory implements MethodLinkBuilderFactory { diff --git a/src/test/java/org/springframework/hateoas/jaxrs/JaxRsLinkBuilderFactoryUnitTest.java b/src/test/java/org/springframework/hateoas/jaxrs/JaxRsLinkBuilderFactoryUnitTest.java index f65447ee..83f5f21c 100644 --- a/src/test/java/org/springframework/hateoas/jaxrs/JaxRsLinkBuilderFactoryUnitTest.java +++ b/src/test/java/org/springframework/hateoas/jaxrs/JaxRsLinkBuilderFactoryUnitTest.java @@ -1,3 +1,18 @@ +/* + * Copyright 2011-2014 the original author or authors. + * + * Licensed 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.springframework.hateoas.jaxrs; import static org.hamcrest.Matchers.*; @@ -14,6 +29,7 @@ import org.springframework.hateoas.TestUtils; * * @author Ricardo Gladwell * @author Oliver Gierke + * @author Kamill Sokol */ public class JaxRsLinkBuilderFactoryUnitTest extends TestUtils { @@ -37,6 +53,18 @@ public class JaxRsLinkBuilderFactoryUnitTest extends TestUtils { assertThat(link.getHref(), endsWith("/people/15/addresses")); } + /** + * @see #96 + */ + @Test + public void createsLinkToParameterizedServiceRootWithUrlEncoding() { + + Link link = factory.linkTo(PersonsAddressesService.class, "with blank").withSelfRel(); + + assertThat(link.getRel(), is(Link.REL_SELF)); + assertThat(link.getHref(), endsWith("/people/with%20blank/addresses")); + } + @Path("/people") interface PersonService { diff --git a/src/test/java/org/springframework/hateoas/mvc/ControllerLinkBuilderFactoryUnitTest.java b/src/test/java/org/springframework/hateoas/mvc/ControllerLinkBuilderFactoryUnitTest.java index abfc9ec9..7e050373 100644 --- a/src/test/java/org/springframework/hateoas/mvc/ControllerLinkBuilderFactoryUnitTest.java +++ b/src/test/java/org/springframework/hateoas/mvc/ControllerLinkBuilderFactoryUnitTest.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2013 the original author or authors. + * Copyright 2012-2014 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,7 +17,7 @@ package org.springframework.hateoas.mvc; import static org.hamcrest.Matchers.*; import static org.junit.Assert.*; -import static org.springframework.hateoas.core.DummyInvocationUtils.*; +import static org.springframework.hateoas.mvc.ControllerLinkBuilder.*; import java.util.Arrays; @@ -29,6 +29,7 @@ import org.springframework.format.annotation.DateTimeFormat; import org.springframework.format.annotation.DateTimeFormat.ISO; import org.springframework.hateoas.Link; import org.springframework.hateoas.TestUtils; +import org.springframework.hateoas.mvc.ControllerLinkBuilderUnitTest.ControllerWithMethods; import org.springframework.hateoas.mvc.ControllerLinkBuilderUnitTest.PersonControllerImpl; import org.springframework.hateoas.mvc.ControllerLinkBuilderUnitTest.PersonsAddressesController; import org.springframework.http.HttpEntity; @@ -41,6 +42,7 @@ import org.springframework.web.util.UriComponentsBuilder; * * @author Ricardo Gladwell * @author Oliver Gierke + * @author Kamill Sokol */ public class ControllerLinkBuilderFactoryUnitTest extends TestUtils { @@ -93,6 +95,30 @@ public class ControllerLinkBuilderFactoryUnitTest extends TestUtils { assertThat(link.getHref(), endsWith("/sample/" + ISODateTimeFormat.date().print(now))); } + /** + * @see #96 + */ + @Test + public void linksToMethodWithPathVariableContainingBlank() { + + Link link = linkTo(methodOn(ControllerWithMethods.class).methodWithPathVariable("with blank")).withSelfRel(); + assertThat(link.getRel(), is(Link.REL_SELF)); + assertThat(link.getHref(), endsWith("/something/with%20blank/foo")); + } + + /** + * @see #96 + */ + @Test + public void createsLinkToParameterizedControllerRootContainingBlank() { + + Link link = factory.linkTo(PersonsAddressesController.class, "with blank").withSelfRel(); + + assertPointsToMockServer(link); + assertThat(link.getRel(), is(Link.REL_SELF)); + assertThat(link.getHref(), endsWith("/people/with%20blank/addresses")); + } + static interface SampleController { @RequestMapping("/sample/{id}") diff --git a/src/test/java/org/springframework/hateoas/mvc/ControllerLinkBuilderUnitTest.java b/src/test/java/org/springframework/hateoas/mvc/ControllerLinkBuilderUnitTest.java index 3cb36a9a..1fac26d6 100644 --- a/src/test/java/org/springframework/hateoas/mvc/ControllerLinkBuilderUnitTest.java +++ b/src/test/java/org/springframework/hateoas/mvc/ControllerLinkBuilderUnitTest.java @@ -42,6 +42,7 @@ import org.springframework.web.util.UriComponentsBuilder; * * @author Oliver Gierke * @author Dietrich Schulten + * @author Kamill Sokol */ public class ControllerLinkBuilderUnitTest extends TestUtils { @@ -343,6 +344,17 @@ public class ControllerLinkBuilderUnitTest extends TestUtils { assertThat(link.getHref(), endsWith("/child/parent")); } + /** + * @see #96 + */ + @Test + public void linksToMethodWithPathVariableContainingBlank() { + + Link link = linkTo(methodOn(ControllerWithMethods.class).methodWithPathVariable("with blank")).withSelfRel(); + assertThat(link.getRel(), is(Link.REL_SELF)); + assertThat(link.getHref(), endsWith("/something/with%20blank/foo")); + } + private static UriComponents toComponents(Link link) { return UriComponentsBuilder.fromUriString(link.getHref()).build(); }