| /* |
| * Copyright (c) 2010, 2018 Oracle and/or its affiliates. All rights reserved. |
| * |
| * This program and the accompanying materials are made available under the |
| * terms of the Eclipse Public License v. 2.0, which is available at |
| * http://www.eclipse.org/legal/epl-2.0. |
| * |
| * This Source Code may also be made available under the following Secondary |
| * Licenses when the conditions for such availability set forth in the |
| * Eclipse Public License v. 2.0 are satisfied: GNU General Public License, |
| * version 2 with the GNU Classpath Exception, which is available at |
| * https://www.gnu.org/software/classpath/license.html. |
| * |
| * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 |
| */ |
| |
| package org.glassfish.jersey.linking; |
| |
| import java.net.URI; |
| import java.util.Arrays; |
| import java.util.Collections; |
| import java.util.HashMap; |
| import java.util.Iterator; |
| import java.util.List; |
| import java.util.Map; |
| import java.util.logging.Filter; |
| import java.util.logging.LogRecord; |
| import java.util.logging.Logger; |
| import java.util.regex.MatchResult; |
| import java.util.zip.ZipEntry; |
| import javax.ws.rs.BeanParam; |
| |
| import javax.ws.rs.GET; |
| import javax.ws.rs.Path; |
| import javax.ws.rs.QueryParam; |
| import javax.ws.rs.core.Link; |
| import javax.ws.rs.core.MultivaluedMap; |
| import javax.ws.rs.core.PathSegment; |
| import javax.ws.rs.core.UriBuilder; |
| |
| import javax.xml.bind.annotation.XmlTransient; |
| |
| import org.glassfish.jersey.internal.util.collection.MultivaluedStringMap; |
| import org.glassfish.jersey.linking.contributing.ResourceLinkContributionContext; |
| import org.glassfish.jersey.linking.mapping.ResourceMappingContext; |
| import org.glassfish.jersey.server.ExtendedUriInfo; |
| import org.glassfish.jersey.server.model.Resource; |
| import org.glassfish.jersey.server.model.ResourceMethod; |
| import org.glassfish.jersey.server.model.RuntimeResource; |
| import org.glassfish.jersey.uri.UriTemplate; |
| |
| import org.junit.Test; |
| import static org.junit.Assert.assertEquals; |
| import static org.junit.Assert.assertTrue; |
| |
| /** |
| * @author Mark Hadley |
| * @author Gerard Davison (gerard.davison at oracle.com) |
| */ |
| public class FieldProcessorTest { |
| |
| private static final Logger LOG = Logger.getLogger(FieldProcessor.class.getName()); |
| |
| ExtendedUriInfo mockUriInfo = new ExtendedUriInfo() { |
| |
| private static final String baseURI = "http://example.com/application/resources"; |
| |
| private MultivaluedMap queryParams = new MultivaluedStringMap(); |
| |
| @Override |
| public String getPath() { |
| throw new UnsupportedOperationException("Not supported yet."); |
| } |
| |
| @Override |
| public String getPath(boolean decode) { |
| throw new UnsupportedOperationException("Not supported yet."); |
| } |
| |
| @Override |
| public List<PathSegment> getPathSegments() { |
| throw new UnsupportedOperationException("Not supported yet."); |
| } |
| |
| @Override |
| public List<PathSegment> getPathSegments(boolean decode) { |
| throw new UnsupportedOperationException("Not supported yet."); |
| } |
| |
| @Override |
| public URI getRequestUri() { |
| throw new UnsupportedOperationException("Not supported yet."); |
| } |
| |
| @Override |
| public UriBuilder getRequestUriBuilder() { |
| throw new UnsupportedOperationException("Not supported yet."); |
| } |
| |
| @Override |
| public URI getAbsolutePath() { |
| throw new UnsupportedOperationException("Not supported yet."); |
| } |
| |
| @Override |
| public UriBuilder getAbsolutePathBuilder() { |
| throw new UnsupportedOperationException("Not supported yet."); |
| } |
| |
| @Override |
| public URI getBaseUri() { |
| return getBaseUriBuilder().build(); |
| } |
| |
| @Override |
| public UriBuilder getBaseUriBuilder() { |
| return UriBuilder.fromUri(baseURI); |
| } |
| |
| @Override |
| public MultivaluedMap<String, String> getPathParameters() { |
| return new MultivaluedStringMap(); |
| } |
| |
| @Override |
| public MultivaluedMap<String, String> getPathParameters(boolean decode) { |
| return new MultivaluedStringMap(); |
| } |
| |
| @Override |
| public MultivaluedMap<String, String> getQueryParameters() { |
| return queryParams; |
| } |
| |
| @Override |
| public MultivaluedMap<String, String> getQueryParameters(boolean decode) { |
| return queryParams; |
| } |
| |
| @Override |
| public List<String> getMatchedURIs() { |
| throw new UnsupportedOperationException("Not supported yet."); |
| } |
| |
| @Override |
| public List<String> getMatchedURIs(boolean decode) { |
| throw new UnsupportedOperationException("Not supported yet."); |
| } |
| |
| @Override |
| public List<Object> getMatchedResources() { |
| Object dummyResource = new Object() { |
| }; |
| return Collections.singletonList(dummyResource); |
| } |
| |
| @Override |
| public Throwable getMappedThrowable() { |
| throw new UnsupportedOperationException("Not supported yet."); |
| } |
| |
| @Override |
| public List<MatchResult> getMatchedResults() { |
| throw new UnsupportedOperationException("Not supported yet."); |
| } |
| |
| @Override |
| public List<UriTemplate> getMatchedTemplates() { |
| throw new UnsupportedOperationException("Not supported yet."); |
| } |
| |
| @Override |
| public List<PathSegment> getPathSegments(String name) { |
| throw new UnsupportedOperationException("Not supported yet."); |
| } |
| |
| @Override |
| public List<PathSegment> getPathSegments(String name, boolean decode) { |
| throw new UnsupportedOperationException("Not supported yet."); |
| } |
| |
| @Override |
| public List<RuntimeResource> getMatchedRuntimeResources() { |
| throw new UnsupportedOperationException("Not supported yet."); |
| } |
| |
| @Override |
| public ResourceMethod getMatchedResourceMethod() { |
| throw new UnsupportedOperationException("Not supported yet."); |
| } |
| |
| @Override |
| public Resource getMatchedModelResource() { |
| throw new UnsupportedOperationException("Not supported yet."); |
| } |
| |
| @Override |
| public List<ResourceMethod> getMatchedResourceLocators() { |
| throw new UnsupportedOperationException("Not supported yet."); |
| } |
| |
| @Override |
| public List<Resource> getLocatorSubResources() { |
| throw new UnsupportedOperationException("Not supported yet."); |
| } |
| |
| @Override |
| public URI resolve(URI uri) { |
| throw new UnsupportedOperationException("Not supported yet."); |
| } |
| |
| @Override |
| public URI relativize(URI uri) { |
| throw new UnsupportedOperationException("Not supported yet."); |
| } |
| }; |
| |
| private final ResourceMappingContext mockRmc = new ResourceMappingContext() { |
| |
| @Override |
| public ResourceMappingContext.Mapping getMapping(Class<?> resource) { |
| return null; |
| } |
| }; |
| |
| protected final ResourceLinkContributionContext mockRlcc = new ResourceLinkContributionContext() { |
| @Override |
| public List<ProvideLinkDescriptor> getContributorsFor(Class<?> entityClass) { |
| return Collections.emptyList(); |
| } |
| }; |
| |
| private static final String TEMPLATE_A = "foo"; |
| |
| public static class TestClassD { |
| |
| @InjectLink(value = TEMPLATE_A, style = InjectLink.Style.RELATIVE_PATH) |
| private String res1; |
| |
| @InjectLink(value = TEMPLATE_A, style = InjectLink.Style.RELATIVE_PATH) |
| private URI res2; |
| } |
| |
| @Test |
| public void testProcessLinks() { |
| LOG.info("Links"); |
| |
| FieldProcessor<TestClassD> instance = new FieldProcessor(TestClassD.class); |
| TestClassD testClass = new TestClassD(); |
| instance.processLinks(testClass, mockUriInfo, mockRmc, mockRlcc); |
| assertEquals(TEMPLATE_A, testClass.res1); |
| assertEquals(TEMPLATE_A, testClass.res2.toString()); |
| } |
| |
| private static final String TEMPLATE_B = "widgets/{id}"; |
| |
| public static class TestClassE { |
| |
| @InjectLink(value = TEMPLATE_B, style = InjectLink.Style.RELATIVE_PATH) |
| private String link; |
| |
| private String id; |
| |
| public TestClassE(String id) { |
| this.id = id; |
| } |
| |
| public String getId() { |
| return id; |
| } |
| } |
| |
| @Test |
| public void testProcessLinksWithFields() { |
| LOG.info("Links from field values"); |
| FieldProcessor<TestClassE> instance = new FieldProcessor(TestClassE.class); |
| TestClassE testClass = new TestClassE("10"); |
| instance.processLinks(testClass, mockUriInfo, mockRmc, mockRlcc); |
| assertEquals("widgets/10", testClass.link); |
| } |
| |
| public static class TestClassF { |
| |
| @InjectLink(value = TEMPLATE_B, style = InjectLink.Style.RELATIVE_PATH) |
| private String thelink; |
| |
| private String id; |
| private TestClassE nested; |
| |
| public TestClassF(String id, TestClassE e) { |
| this.id = id; |
| this.nested = e; |
| } |
| |
| public String getId() { |
| return id; |
| } |
| } |
| |
| @Test |
| public void testNesting() { |
| LOG.info("Nesting"); |
| FieldProcessor<TestClassF> instance = new FieldProcessor(TestClassF.class); |
| TestClassE nested = new TestClassE("10"); |
| TestClassF testClass = new TestClassF("20", nested); |
| instance.processLinks(testClass, mockUriInfo, mockRmc, mockRlcc); |
| assertEquals("widgets/20", testClass.thelink); |
| assertEquals("widgets/10", testClass.nested.link); |
| } |
| |
| @Test |
| public void testArray() { |
| LOG.info("Array"); |
| FieldProcessor<TestClassE[]> instance = new FieldProcessor(TestClassE[].class); |
| TestClassE item1 = new TestClassE("10"); |
| TestClassE item2 = new TestClassE("20"); |
| TestClassE array[] = {item1, item2}; |
| instance.processLinks(array, mockUriInfo, mockRmc, mockRlcc); |
| assertEquals("widgets/10", array[0].link); |
| assertEquals("widgets/20", array[1].link); |
| } |
| |
| @Test |
| public void testCollection() { |
| LOG.info("Collection"); |
| FieldProcessor<List> instance = new FieldProcessor(List.class); |
| TestClassE item1 = new TestClassE("10"); |
| TestClassE item2 = new TestClassE("20"); |
| List<TestClassE> list = Arrays.asList(item1, item2); |
| instance.processLinks(list, mockUriInfo, mockRmc, mockRlcc); |
| assertEquals("widgets/10", list.get(0).link); |
| assertEquals("widgets/20", list.get(1).link); |
| } |
| |
| @Test |
| public void testMap() { |
| LOG.info("Map"); |
| FieldProcessor<Map> instance = new FieldProcessor(Map.class); |
| TestClassE item1 = new TestClassE("10"); |
| TestClassE item2 = new TestClassE("20"); |
| Map<String, TestClassE> map = new HashMap<>(); |
| for (TestClassE item : Arrays.asList(item1, item2)) { |
| map.put(item.getId(), item); |
| } |
| instance.processLinks(map, mockUriInfo, mockRmc, mockRlcc); |
| assertEquals("widgets/10", map.get("10").link); |
| assertEquals("widgets/20", map.get("20").link); |
| } |
| |
| public static class TestClassG { |
| |
| @InjectLink(value = TEMPLATE_B, style = InjectLink.Style.RELATIVE_PATH) |
| private String relativePath; |
| |
| @InjectLink(value = TEMPLATE_B, style = InjectLink.Style.ABSOLUTE_PATH) |
| private String absolutePath; |
| |
| @InjectLink(value = TEMPLATE_B, style = InjectLink.Style.ABSOLUTE) |
| private String absolute; |
| |
| @InjectLink(TEMPLATE_B) |
| private String defaultStyle; |
| |
| private String id; |
| |
| public TestClassG(String id) { |
| this.id = id; |
| } |
| |
| public String getId() { |
| return id; |
| } |
| } |
| |
| @Test |
| public void testLinkStyles() { |
| LOG.info("Link styles"); |
| FieldProcessor<TestClassG> instance = new FieldProcessor(TestClassG.class); |
| TestClassG testClass = new TestClassG("10"); |
| instance.processLinks(testClass, mockUriInfo, mockRmc, mockRlcc); |
| assertEquals("widgets/10", testClass.relativePath); |
| assertEquals("/application/resources/widgets/10", testClass.absolutePath); |
| assertEquals("/application/resources/widgets/10", testClass.defaultStyle); |
| assertEquals("http://example.com/application/resources/widgets/10", testClass.absolute); |
| } |
| |
| public static class TestClassH { |
| |
| @InjectLink(TEMPLATE_B) |
| private String link; |
| |
| public String getId() { |
| return "10"; |
| } |
| } |
| |
| @Test |
| public void testComputedProperty() { |
| LOG.info("Computed property"); |
| FieldProcessor<TestClassH> instance = new FieldProcessor(TestClassH.class); |
| TestClassH testClass = new TestClassH(); |
| instance.processLinks(testClass, mockUriInfo, mockRmc, mockRlcc); |
| assertEquals("/application/resources/widgets/10", testClass.link); |
| } |
| |
| public static class TestClassI { |
| |
| @InjectLink("widgets/${entity.id}") |
| private String link; |
| |
| public String getId() { |
| return "10"; |
| } |
| } |
| |
| @Test |
| public void testEL() { |
| LOG.info("El link"); |
| FieldProcessor<TestClassI> instance = new FieldProcessor(TestClassI.class); |
| TestClassI testClass = new TestClassI(); |
| instance.processLinks(testClass, mockUriInfo, mockRmc, mockRlcc); |
| assertEquals("/application/resources/widgets/10", testClass.link); |
| } |
| |
| public static class TestClassJ { |
| |
| @InjectLink("widgets/${entity.id}/widget/{id}") |
| private String link; |
| |
| public String getId() { |
| return "10"; |
| } |
| } |
| |
| @Test |
| public void testMixed() { |
| LOG.info("Mixed EL and template vars link"); |
| FieldProcessor<TestClassJ> instance = new FieldProcessor(TestClassJ.class); |
| TestClassJ testClass = new TestClassJ(); |
| instance.processLinks(testClass, mockUriInfo, mockRmc, mockRlcc); |
| assertEquals("/application/resources/widgets/10/widget/10", testClass.link); |
| } |
| |
| public static class DependentInnerBean { |
| |
| @InjectLink("${entity.id}") |
| public String outerUri; |
| @InjectLink("${instance.id}") |
| public String innerUri; |
| |
| public String getId() { |
| return "inner"; |
| } |
| } |
| |
| public static class OuterBean { |
| |
| public DependentInnerBean inner = new DependentInnerBean(); |
| |
| public String getId() { |
| return "outer"; |
| } |
| } |
| |
| @Test |
| public void testELScopes() { |
| LOG.info("EL scopes"); |
| FieldProcessor<OuterBean> instance = new FieldProcessor(OuterBean.class); |
| OuterBean testClass = new OuterBean(); |
| instance.processLinks(testClass, mockUriInfo, mockRmc, mockRlcc); |
| assertEquals("/application/resources/inner", testClass.inner.innerUri); |
| assertEquals("/application/resources/outer", testClass.inner.outerUri); |
| } |
| |
| public static class BoundLinkBean { |
| |
| @InjectLink(value = "{id}", bindings = {@Binding(name = "id", value = "${instance.name}")}) |
| public String uri; |
| |
| public String getName() { |
| return "name"; |
| } |
| } |
| |
| @Test |
| public void testELBinding() { |
| LOG.info("EL binding"); |
| FieldProcessor<BoundLinkBean> instance = new FieldProcessor(BoundLinkBean.class); |
| BoundLinkBean testClass = new BoundLinkBean(); |
| instance.processLinks(testClass, mockUriInfo, mockRmc, mockRlcc); |
| assertEquals("/application/resources/name", testClass.uri); |
| } |
| |
| public static class BoundLinkOnLinkBean { |
| |
| @InjectLink(value = "{id}", |
| bindings = {@Binding(name = "id", value = "${instance.name}")}, |
| rel = "self") |
| public Link link; |
| |
| public String getName() { |
| return "name"; |
| } |
| } |
| |
| @Test |
| public void testELBindingOnLink() { |
| LOG.info("EL binding"); |
| FieldProcessor<BoundLinkOnLinkBean> instance = new FieldProcessor(BoundLinkOnLinkBean.class); |
| BoundLinkOnLinkBean testClass = new BoundLinkOnLinkBean(); |
| instance.processLinks(testClass, mockUriInfo, mockRmc, mockRlcc); |
| assertEquals("/application/resources/name", testClass.link.getUri().toString()); |
| assertEquals("self", testClass.link.getRel()); |
| } |
| |
| public static class BoundLinkOnLinksBean { |
| |
| @InjectLinks({ |
| @InjectLink(value = "{id}", |
| bindings = {@Binding(name = "id", value = "${instance.name}")}, |
| rel = "self"), |
| @InjectLink(value = "{id}", |
| bindings = {@Binding(name = "id", value = "${instance.name}")}, |
| rel = "other"), |
| |
| }) |
| public List<Link> links; |
| |
| @InjectLinks({ |
| @InjectLink(value = "{id}", |
| bindings = {@Binding(name = "id", value = "${instance.name}")}, |
| rel = "self"), |
| @InjectLink(value = "{id}", |
| bindings = {@Binding(name = "id", value = "${instance.name}")}, |
| rel = "other"), |
| |
| }) |
| public Link[] linksArray; |
| |
| public String getName() { |
| return "name"; |
| } |
| } |
| |
| @Test |
| public void testELBindingOnLinks() { |
| LOG.info("EL binding"); |
| FieldProcessor<BoundLinkOnLinksBean> instance = new FieldProcessor(BoundLinkOnLinksBean.class); |
| BoundLinkOnLinksBean testClass = new BoundLinkOnLinksBean(); |
| instance.processLinks(testClass, mockUriInfo, mockRmc, mockRlcc); |
| assertEquals("/application/resources/name", testClass.links.get(0).getUri().toString()); |
| assertEquals("self", testClass.links.get(0).getRel()); |
| assertEquals("other", testClass.links.get(1).getRel()); |
| |
| assertEquals("/application/resources/name", testClass.linksArray[0].getUri().toString()); |
| assertEquals("self", testClass.linksArray[0].getRel()); |
| assertEquals("other", testClass.linksArray[1].getRel()); |
| |
| } |
| |
| public static class ConditionalLinkBean { |
| |
| @InjectLink(value = "{id}", condition = "${entity.uri1Enabled}") |
| public String uri1; |
| |
| @InjectLink(value = "{id}", condition = "${entity.uri2Enabled}") |
| public String uri2; |
| |
| public String getId() { |
| return "name"; |
| } |
| |
| public boolean isUri1Enabled() { |
| return true; |
| } |
| |
| public boolean isUri2Enabled() { |
| return false; |
| } |
| } |
| |
| @Test |
| public void testCondition() { |
| LOG.info("Condition"); |
| FieldProcessor<ConditionalLinkBean> instance = new FieldProcessor(ConditionalLinkBean.class); |
| ConditionalLinkBean testClass = new ConditionalLinkBean(); |
| instance.processLinks(testClass, mockUriInfo, mockRmc, mockRlcc); |
| assertEquals("/application/resources/name", testClass.uri1); |
| assertEquals(null, testClass.uri2); |
| } |
| |
| @Path("a") |
| public static class SubResource { |
| |
| @Path("b") |
| @GET |
| public String getB() { |
| return "hello world"; |
| } |
| } |
| |
| public static class SubResourceBean { |
| |
| @InjectLink(resource = SubResource.class, method = "getB") |
| public String uri; |
| } |
| |
| @Test |
| public void testSubresource() { |
| LOG.info("Subresource"); |
| FieldProcessor<SubResourceBean> instance = new FieldProcessor(SubResourceBean.class); |
| SubResourceBean testClass = new SubResourceBean(); |
| instance.processLinks(testClass, mockUriInfo, mockRmc, mockRlcc); |
| assertEquals("/application/resources/a/b", testClass.uri); |
| } |
| |
| @Path("a") |
| public static class QueryResource { |
| |
| @Path("b") |
| @GET |
| public String getB(@QueryParam("query") String query, @QueryParam("query2") String query2) { |
| return "hello world"; |
| } |
| } |
| |
| public static class QueryResourceBean { |
| |
| public String getQueryParam() { |
| return queryExample; |
| } |
| |
| private String queryExample; |
| |
| public QueryResourceBean(String queryExample, String queryExample2) { |
| this.queryExample = queryExample; |
| this.queryExample2 = queryExample2; |
| } |
| |
| public String getQueryParam2() { |
| return queryExample2; |
| } |
| |
| private String queryExample2; |
| |
| @InjectLink(resource = QueryResource.class, method = "getB", |
| bindings = { |
| @Binding(name = "query", value = "${instance.queryParam}"), |
| @Binding(name = "query2", value = "${instance.queryParam2}") |
| }) |
| public String uri; |
| } |
| |
| public static class QueryResourceBeanNoBindings { |
| //query parameters will be populated from uriInfo |
| //JERSEY-2863 |
| @InjectLink(resource = QueryResource.class, method = "getB") |
| public String uri; |
| } |
| |
| @Test |
| public void testQueryResource() { |
| LOG.info("QueryResource"); |
| FieldProcessor<QueryResourceBean> instance = new FieldProcessor(QueryResourceBean.class); |
| QueryResourceBean testClass = new QueryResourceBean("queryExample", null); |
| instance.processLinks(testClass, mockUriInfo, mockRmc, mockRlcc); |
| assertEquals("/application/resources/a/b?query=queryExample&query2=", testClass.uri); |
| } |
| |
| @Test |
| public void testDoubleQueryResource() { |
| LOG.info("QueryResource"); |
| FieldProcessor<QueryResourceBean> instance = new FieldProcessor(QueryResourceBean.class); |
| QueryResourceBean testClass = new QueryResourceBean("queryExample", "queryExample2"); |
| instance.processLinks(testClass, mockUriInfo, mockRmc, mockRlcc); |
| assertEquals("/application/resources/a/b?query=queryExample&query2=queryExample2", testClass.uri); |
| } |
| |
| @Test |
| public void testQueryResourceWithoutBindings() { |
| LOG.info("QueryResource"); |
| FieldProcessor<QueryResourceBeanNoBindings> instance = new FieldProcessor(QueryResourceBeanNoBindings.class); |
| QueryResourceBeanNoBindings testClass = new QueryResourceBeanNoBindings(); |
| mockUriInfo.getQueryParameters().putSingle("query", "queryExample"); |
| mockUriInfo.getQueryParameters().putSingle("query2", "queryExample2"); |
| assertEquals("queryExample", mockUriInfo.getQueryParameters().getFirst("query")); |
| instance.processLinks(testClass, mockUriInfo, mockRmc, mockRlcc); |
| assertEquals("/application/resources/a/b?query=queryExample&query2=queryExample2", testClass.uri); |
| //clean mock |
| mockUriInfo.getQueryParameters().clear(); |
| } |
| |
| /** Bean param with method setter QueryParam. */ |
| public static class BeanParamBeanA { |
| private String qparam; |
| @QueryParam("qparam") |
| public void setQParam(String qparam) { |
| this.qparam = qparam; |
| } |
| } |
| |
| /** Bean param with field QueryParam. */ |
| public static class BeanParamBeanB { |
| @QueryParam("query") public String query; |
| } |
| |
| @Path("a") |
| public static class BeanParamQueryResource { |
| |
| @Path("b") |
| @GET |
| public String getB(@BeanParam BeanParamBeanA beanParamBeanA, @BeanParam BeanParamBeanB beanParamBeanB) { |
| return "hello world"; |
| } |
| } |
| |
| public static class BeanParamResourceBean { |
| |
| public String getQueryParam() { |
| return queryExample; |
| } |
| |
| private String queryExample; |
| |
| public BeanParamResourceBean(String queryExample) { |
| this.queryExample = queryExample; |
| } |
| |
| @InjectLink(resource = BeanParamQueryResource.class, method = "getB", |
| bindings = { |
| @Binding(name = "query", value = "${instance.queryParam}"), |
| @Binding(name = "qparam", value = "foo") |
| }) |
| public String uri; |
| } |
| |
| @Test |
| public void testBeanParamResource() { |
| LOG.info("BeanParamResource"); |
| FieldProcessor<BeanParamResourceBean> instance = new FieldProcessor(BeanParamResourceBean.class); |
| BeanParamResourceBean testClass = new BeanParamResourceBean("queryExample"); |
| instance.processLinks(testClass, mockUriInfo, mockRmc, mockRlcc); |
| assertEquals("/application/resources/a/b?qparam=foo&query=queryExample", testClass.uri); |
| } |
| |
| public static class TestClassK { |
| |
| public static final ZipEntry zipEntry = new ZipEntry("entry"); |
| } |
| |
| public static class TestClassL { |
| |
| public final ZipEntry zipEntry = new ZipEntry("entry"); |
| } |
| |
| private class LoggingFilter implements Filter { |
| |
| private int count = 0; |
| |
| @Override |
| public synchronized boolean isLoggable(LogRecord logRecord) { |
| if (logRecord.getThrown() instanceof IllegalAccessException) { |
| count++; |
| return false; |
| } |
| return true; |
| } |
| |
| public int getCount() { |
| return count; |
| } |
| } |
| |
| @Test |
| public void testKL() { |
| final LoggingFilter lf = new LoggingFilter(); |
| |
| Logger.getLogger(FieldDescriptor.class.getName()).setFilter(lf); |
| assertTrue(lf.getCount() == 0); |
| |
| FieldProcessor<TestClassK> instanceK = new FieldProcessor(TestClassK.class); |
| TestClassK testClassK = new TestClassK(); |
| instanceK.processLinks(testClassK, mockUriInfo, mockRmc, mockRlcc); |
| |
| assertTrue(lf.getCount() == 0); |
| |
| FieldProcessor<TestClassL> instanceL = new FieldProcessor(TestClassL.class); |
| TestClassL testClassL = new TestClassL(); |
| instanceL.processLinks(testClassL, mockUriInfo, mockRmc, mockRlcc); |
| |
| assertTrue(lf.getCount() == 0); |
| |
| Logger.getLogger(FieldDescriptor.class.getName()).setFilter(null); |
| |
| } |
| |
| public static class TestClassM { |
| |
| @InjectLink(value = TEMPLATE_B, style = InjectLink.Style.RELATIVE_PATH) |
| private String thelink; |
| |
| private String id; |
| |
| @InjectLinkNoFollow |
| private TestClassE nested; |
| |
| @XmlTransient |
| private TestClassE transientNested; |
| |
| public TestClassM(String id, TestClassE e, TestClassE transientNested) { |
| this.id = id; |
| this.nested = e; |
| this.transientNested = transientNested; |
| } |
| |
| public String getId() { |
| return id; |
| } |
| } |
| |
| @Test |
| public void testNoRecursiveNesting() { |
| LOG.info("No Recursive Nesting"); |
| FieldProcessor<TestClassM> instance = new FieldProcessor(TestClassM.class); |
| TestClassE nested = new TestClassE("10"); |
| TestClassE transientNested = new TestClassE("30"); |
| TestClassM testClass = new TestClassM("20", nested, transientNested); |
| instance.processLinks(testClass, mockUriInfo, mockRmc, mockRlcc); |
| assertEquals("widgets/20", testClass.thelink); |
| assertEquals(null, testClass.nested.link); |
| assertEquals(null, testClass.transientNested.link); |
| } |
| |
| public static class TestClassN { |
| // Simulate object injected by JPA |
| // in order to test a fix for JERSEY-2625 |
| private transient Iterable res1 = new Iterable() { |
| @Override |
| public Iterator iterator() { |
| throw new RuntimeException("Declarative linking feature is incorrectly processing a transient iterator"); |
| } |
| |
| }; |
| } |
| |
| @Test |
| public void testIgnoreTransient() { |
| TestClassN testClass = new TestClassN(); |
| FieldProcessor<TestClassN> instance = new FieldProcessor(TestClassN.class); |
| instance.processLinks(testClass, mockUriInfo, mockRmc, mockRlcc); |
| } |
| |
| } |