diff --git a/docs/src/main/docbook/declarative-linking.xml b/docs/src/main/docbook/declarative-linking.xml index f02b5f6399..f37eabc762 100644 --- a/docs/src/main/docbook/declarative-linking.xml +++ b/docs/src/main/docbook/declarative-linking.xml @@ -396,6 +396,58 @@ final Application application = new ResourceConfig() .packages("org.glassfish.jersey.examples.linking") .register(DeclarativeLinkingFeature.class); + + You can also change the default linking style for the whole application. Either by using the constructor of + DeclarativeLinkingFeature, or by setting the config value for + DeclarativeLinkingFeature.DEFAULT_LINK_STYLE. + + + Creating JAX-RS application with Declarative Linking and default link style set to ABSOLUTE. + + // Create JAX-RS application. +final Application application = new ResourceConfig() + .packages("org.glassfish.jersey.examples.linking") + .register(new DeclarativeLinkingFeature(InjectLink.Style.ABSOLUTE)); + + + The default value will be overridden if it is defined on the annotation + @InjectLink/@ProvideLink. + + + + + Possible values are: + + + + ABSOLUTE + + + + An absolute URI. The URI template will be prefixed with the absolute base URI of the application. + + + + + + ABSOLUTE_PATH + + + + An absolute path. The URI template will be prefixed with the absolute base path of the application. + This is also the DEFAULT behavior if nothing else is set. + + + + + + RELATIVE_PATH + + + A relative path. The URI template will be converted to a relative path with no prefix. + + + diff --git a/examples/declarative-linking/src/main/java/org/glassfish/jersey/examples/linking/representation/ItemsRepresentation.java b/examples/declarative-linking/src/main/java/org/glassfish/jersey/examples/linking/representation/ItemsRepresentation.java index 7dfc0fb6d9..3aa0e22987 100644 --- a/examples/declarative-linking/src/main/java/org/glassfish/jersey/examples/linking/representation/ItemsRepresentation.java +++ b/examples/declarative-linking/src/main/java/org/glassfish/jersey/examples/linking/representation/ItemsRepresentation.java @@ -56,7 +56,6 @@ import org.glassfish.jersey.examples.linking.resources.ItemsResource; import org.glassfish.jersey.linking.Binding; import org.glassfish.jersey.linking.InjectLink; -import org.glassfish.jersey.linking.InjectLink.Style; import org.glassfish.jersey.linking.InjectLinks; /** @@ -70,7 +69,6 @@ @InjectLinks({ @InjectLink( resource = ItemsResource.class, - style = Style.ABSOLUTE, method = "query", condition = "${instance.offset + instance.limit < instance.modelLimit}", bindings = { @@ -81,7 +79,6 @@ ), @InjectLink( resource = ItemsResource.class, - style = Style.ABSOLUTE, method = "query", condition = "${instance.offset - instance.limit >= 0}", bindings = { @@ -105,7 +102,6 @@ public class ItemsRepresentation { @InjectLink( resource = ItemsResource.class, method = "query", - style = Style.ABSOLUTE, bindings = {@Binding(name = "offset", value = "${instance.offset}"), @Binding(name = "limit", value = "${instance.limit}") }, @@ -118,7 +114,6 @@ public class ItemsRepresentation { @InjectLinks({ @InjectLink( resource = ItemsResource.class, - style = Style.ABSOLUTE, method = "query", condition = "${instance.offset + instance.limit < instance.modelLimit}", bindings = { @@ -129,7 +124,6 @@ public class ItemsRepresentation { ), @InjectLink( resource = ItemsResource.class, - style = Style.ABSOLUTE, method = "query", condition = "${instance.offset - instance.limit >= 0}", bindings = { diff --git a/examples/declarative-linking/src/test/java/org/glassfish/jersey/examples/linking/LinkWebAppTest.java b/examples/declarative-linking/src/test/java/org/glassfish/jersey/examples/linking/LinkWebAppTest.java index dd51c2c546..99e21d2a2f 100644 --- a/examples/declarative-linking/src/test/java/org/glassfish/jersey/examples/linking/LinkWebAppTest.java +++ b/examples/declarative-linking/src/test/java/org/glassfish/jersey/examples/linking/LinkWebAppTest.java @@ -47,6 +47,7 @@ import org.glassfish.jersey.examples.linking.resources.ItemsResource; import org.glassfish.jersey.linking.DeclarativeLinkingFeature; +import org.glassfish.jersey.linking.InjectLink; import org.glassfish.jersey.server.ResourceConfig; import org.glassfish.jersey.test.JerseyTest; import org.glassfish.jersey.test.TestProperties; @@ -66,7 +67,7 @@ public class LinkWebAppTest extends JerseyTest { protected ResourceConfig configure() { enable(TestProperties.LOG_TRAFFIC); final ResourceConfig rc = new ResourceConfig(ItemsResource.class); - rc.register(DeclarativeLinkingFeature.class); + rc.register(new DeclarativeLinkingFeature(InjectLink.Style.ABSOLUTE)); return rc; } diff --git a/incubator/declarative-linking/pom.xml b/incubator/declarative-linking/pom.xml index 7add6b866c..3e94aad016 100644 --- a/incubator/declarative-linking/pom.xml +++ b/incubator/declarative-linking/pom.xml @@ -106,6 +106,11 @@ 1.4.0 test + + org.mockito + mockito-all + test + diff --git a/incubator/declarative-linking/src/main/java/org/glassfish/jersey/linking/DeclarativeLinkingFeature.java b/incubator/declarative-linking/src/main/java/org/glassfish/jersey/linking/DeclarativeLinkingFeature.java index ac203af091..fa1174f57f 100644 --- a/incubator/declarative-linking/src/main/java/org/glassfish/jersey/linking/DeclarativeLinkingFeature.java +++ b/incubator/declarative-linking/src/main/java/org/glassfish/jersey/linking/DeclarativeLinkingFeature.java @@ -62,10 +62,36 @@ @Beta public class DeclarativeLinkingFeature implements Feature { + /** + * Sets the default link Style for this feature, see {@link InjectLink.Style} for the possible values. + */ + public static final String DEFAULT_LINK_STYLE = "org.glassfish.jersey.linking.default.link.style"; + + private final InjectLink.Style defaultLinkStyle; + + public DeclarativeLinkingFeature(InjectLink.Style defaultLinkStyle) { + + this.defaultLinkStyle = defaultLinkStyle; + } + + public DeclarativeLinkingFeature(){ + this(null); + } + @Override public boolean configure(FeatureContext context) { Configuration config = context.getConfiguration(); + + Object linkStyle = (defaultLinkStyle == null) ? config.getProperty(DEFAULT_LINK_STYLE) : defaultLinkStyle; + if (linkStyle instanceof String) { + context.property(DEFAULT_LINK_STYLE, InjectLink.Style.valueOf(((String) linkStyle).toUpperCase())); + } else if (linkStyle instanceof InjectLink.Style){ + context.property(DEFAULT_LINK_STYLE, linkStyle); + } else if (linkStyle == null) { + context.property(DEFAULT_LINK_STYLE, InjectLink.Style.DEFAULT); + } + if (!config.isRegistered(ResponseLinkFilter.class)) { context.register(new AbstractBinder() { diff --git a/incubator/declarative-linking/src/main/java/org/glassfish/jersey/linking/ELLinkBuilder.java b/incubator/declarative-linking/src/main/java/org/glassfish/jersey/linking/ELLinkBuilder.java index bf82de9ab8..f76cccc4fb 100644 --- a/incubator/declarative-linking/src/main/java/org/glassfish/jersey/linking/ELLinkBuilder.java +++ b/incubator/declarative-linking/src/main/java/org/glassfish/jersey/linking/ELLinkBuilder.java @@ -119,19 +119,24 @@ static URI buildURI(InjectLinkDescriptor link, template = expr.getValue(context).toString(); // now process any embedded URI template parameters - UriBuilder ub = applyLinkStyle(template, link.getLinkStyle(), uriInfo); + UriBuilder ub = applyLinkStyle(template, link.getLinkStyle(), rmc.getLinkStyle(), uriInfo); UriTemplateParser parser = new UriTemplateParser(template); List parameterNames = parser.getNames(); Map valueMap = getParameterValues(parameterNames, link, context, uriInfo); return ub.buildFromMap(valueMap); } - private static UriBuilder applyLinkStyle(String template, InjectLink.Style style, UriInfo uriInfo) { + private static UriBuilder applyLinkStyle(String template, + InjectLink.Style linkStyle, + InjectLink.Style contextStyle, + UriInfo uriInfo) { UriBuilder ub = null; + InjectLink.Style style = (linkStyle == InjectLink.Style.DEFAULT) ? contextStyle : linkStyle; switch (style) { case ABSOLUTE: ub = uriInfo.getBaseUriBuilder().path(template); break; + case DEFAULT: case ABSOLUTE_PATH: String basePath = uriInfo.getBaseUri().getPath(); ub = UriBuilder.fromPath(basePath).path(template); diff --git a/incubator/declarative-linking/src/main/java/org/glassfish/jersey/linking/InjectLink.java b/incubator/declarative-linking/src/main/java/org/glassfish/jersey/linking/InjectLink.java index ffbc1face2..216442619f 100644 --- a/incubator/declarative-linking/src/main/java/org/glassfish/jersey/linking/InjectLink.java +++ b/incubator/declarative-linking/src/main/java/org/glassfish/jersey/linking/InjectLink.java @@ -81,14 +81,20 @@ enum Style { * A relative path. The URI template will be converted to a relative * path with no prefix. */ - RELATIVE_PATH + RELATIVE_PATH, + + /** + * Default style which can be configured for all links by {@link DeclarativeLinkingFeature#DEFAULT_LINK_STYLE}. + * If both are {@code DEFAULT} then it will use the {@link #ABSOLUTE_PATH} style. + */ + DEFAULT } /** * The style of URI to inject */ - Style style() default Style.ABSOLUTE_PATH; + Style style() default Style.DEFAULT; /** * Specifies a URI template that will be used to build the injected URI. The diff --git a/incubator/declarative-linking/src/main/java/org/glassfish/jersey/linking/ProvideLink.java b/incubator/declarative-linking/src/main/java/org/glassfish/jersey/linking/ProvideLink.java index 51aa02838b..d2facf4c9c 100644 --- a/incubator/declarative-linking/src/main/java/org/glassfish/jersey/linking/ProvideLink.java +++ b/incubator/declarative-linking/src/main/java/org/glassfish/jersey/linking/ProvideLink.java @@ -79,7 +79,7 @@ /** * The style of URI to inject */ - InjectLink.Style style() default InjectLink.Style.ABSOLUTE_PATH; + InjectLink.Style style() default InjectLink.Style.DEFAULT; /** * Provide links for representation classes listed here. diff --git a/incubator/declarative-linking/src/main/java/org/glassfish/jersey/linking/mapping/NaiveResourceMappingContext.java b/incubator/declarative-linking/src/main/java/org/glassfish/jersey/linking/mapping/NaiveResourceMappingContext.java index b2c1c13fc6..13f83dd6c5 100644 --- a/incubator/declarative-linking/src/main/java/org/glassfish/jersey/linking/mapping/NaiveResourceMappingContext.java +++ b/incubator/declarative-linking/src/main/java/org/glassfish/jersey/linking/mapping/NaiveResourceMappingContext.java @@ -46,9 +46,11 @@ import java.util.LinkedList; import java.util.List; import java.util.Map; - +import javax.ws.rs.core.Configuration; import javax.ws.rs.core.Context; +import org.glassfish.jersey.linking.DeclarativeLinkingFeature; +import org.glassfish.jersey.linking.InjectLink; import org.glassfish.jersey.process.Inflector; import org.glassfish.jersey.server.ExtendedResourceContext; import org.glassfish.jersey.server.model.HandlerConstructor; @@ -76,8 +78,11 @@ public class NaiveResourceMappingContext implements ResourceMappingContext { private Map, ResourceMappingContext.Mapping> mappings; - public NaiveResourceMappingContext(@Context final ExtendedResourceContext erc) { + private final InjectLink.Style linkStyle; + + public NaiveResourceMappingContext(@Context final ExtendedResourceContext erc, @Context Configuration configuration) { this.erc = erc; + this.linkStyle = (InjectLink.Style) configuration.getProperty(DeclarativeLinkingFeature.DEFAULT_LINK_STYLE); } @Override @@ -86,6 +91,11 @@ public Mapping getMapping(final Class resource) { return mappings.get(resource); } + @Override + public InjectLink.Style getLinkStyle() { + return linkStyle; + } + private void buildMappings() { if (mappings != null) { return; diff --git a/incubator/declarative-linking/src/main/java/org/glassfish/jersey/linking/mapping/ResourceMappingContext.java b/incubator/declarative-linking/src/main/java/org/glassfish/jersey/linking/mapping/ResourceMappingContext.java index 3e016cd801..637745ce72 100644 --- a/incubator/declarative-linking/src/main/java/org/glassfish/jersey/linking/mapping/ResourceMappingContext.java +++ b/incubator/declarative-linking/src/main/java/org/glassfish/jersey/linking/mapping/ResourceMappingContext.java @@ -40,6 +40,7 @@ package org.glassfish.jersey.linking.mapping; +import org.glassfish.jersey.linking.InjectLink; import org.glassfish.jersey.uri.UriTemplate; /** @@ -51,10 +52,12 @@ public interface ResourceMappingContext { - public interface Mapping { + interface Mapping { - public UriTemplate getTemplate(); + UriTemplate getTemplate(); } - public Mapping getMapping(Class resource); + Mapping getMapping(Class resource); + + InjectLink.Style getLinkStyle(); } diff --git a/incubator/declarative-linking/src/test/java/org/glassfish/jersey/linking/EntityDescriptorTest.java b/incubator/declarative-linking/src/test/java/org/glassfish/jersey/linking/EntityDescriptorTest.java index 7e17315050..e445b5bf15 100644 --- a/incubator/declarative-linking/src/test/java/org/glassfish/jersey/linking/EntityDescriptorTest.java +++ b/incubator/declarative-linking/src/test/java/org/glassfish/jersey/linking/EntityDescriptorTest.java @@ -75,6 +75,11 @@ public static class TestClassA { public ResourceMappingContext.Mapping getMapping(Class resource) { return null; } + + @Override + public InjectLink.Style getLinkStyle() { + return InjectLink.Style.DEFAULT; + } }; /** diff --git a/incubator/declarative-linking/src/test/java/org/glassfish/jersey/linking/FieldProcessorTest.java b/incubator/declarative-linking/src/test/java/org/glassfish/jersey/linking/FieldProcessorTest.java index 3f14fe3d3a..7b8c471934 100644 --- a/incubator/declarative-linking/src/test/java/org/glassfish/jersey/linking/FieldProcessorTest.java +++ b/incubator/declarative-linking/src/test/java/org/glassfish/jersey/linking/FieldProcessorTest.java @@ -74,6 +74,7 @@ import org.glassfish.jersey.uri.UriTemplate; import org.junit.Test; +import org.mockito.Mockito; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; @@ -245,6 +246,11 @@ public URI relativize(URI uri) { public ResourceMappingContext.Mapping getMapping(Class resource) { return null; } + + @Override + public InjectLink.Style getLinkStyle() { + return InjectLink.Style.DEFAULT; + } }; protected final ResourceLinkContributionContext mockRlcc = new ResourceLinkContributionContext() { @@ -408,6 +414,34 @@ public void testLinkStyles() { assertEquals("http://example.com/application/resources/widgets/10", testClass.absolute); } + @Test + public void testDefaultLinkStylesCanBeOverridden() { + LOG.info("Link styles default"); + FieldProcessor instance = new FieldProcessor(TestClassG.class); + ResourceMappingContext resourceMappingContext = Mockito.mock(ResourceMappingContext.class); + for (InjectLink.Style style : Arrays.asList(InjectLink.Style.values())) { + Mockito.when(resourceMappingContext.getLinkStyle()).thenReturn(style); + TestClassG testClass = new TestClassG("10"); + instance.processLinks(testClass, mockUriInfo, resourceMappingContext, mockRlcc); + assertEquals("widgets/10", testClass.relativePath); + assertEquals("/application/resources/widgets/10", testClass.absolutePath); + assertEquals("http://example.com/application/resources/widgets/10", testClass.absolute); + switch (style) { + case ABSOLUTE: + assertEquals("http://example.com/application/resources/widgets/10", testClass.defaultStyle); + break; + case DEFAULT: + case ABSOLUTE_PATH: + assertEquals("/application/resources/widgets/10", testClass.defaultStyle); + break; + case RELATIVE_PATH: + assertEquals("widgets/10", testClass.defaultStyle); + break; + } + + } + } + public static class TestClassH { @InjectLink(TEMPLATE_B) diff --git a/incubator/declarative-linking/src/test/java/org/glassfish/jersey/linking/HeaderProcessorTest.java b/incubator/declarative-linking/src/test/java/org/glassfish/jersey/linking/HeaderProcessorTest.java index 2021ebedb1..0192293b28 100644 --- a/incubator/declarative-linking/src/test/java/org/glassfish/jersey/linking/HeaderProcessorTest.java +++ b/incubator/declarative-linking/src/test/java/org/glassfish/jersey/linking/HeaderProcessorTest.java @@ -223,6 +223,11 @@ public List getLocatorSubResources() { public ResourceMappingContext.Mapping getMapping(Class resource) { return null; } + + @Override + public InjectLink.Style getLinkStyle() { + return InjectLink.Style.DEFAULT; + } }; @InjectLink(value = "A")