View Javadoc

1   package com.atlassian.plugins.rest.module.util;
2   
3   import com.atlassian.plugins.rest.common.util.RestUrlBuilder;
4   import org.springframework.util.Assert;
5   
6   import javax.ws.rs.core.Response;
7   import javax.ws.rs.ext.RuntimeDelegate;
8   import java.net.URI;
9   
10  /**
11   * @since 2.2
12   */
13  public class RestUrlBuilderImpl implements RestUrlBuilder {
14      public RestUrlBuilderImpl() {
15          /**
16           * IMPLEMENTATION NOTE:
17           *
18           * <p>
19           * We're forcing jsr311 to initialize itself now that the context
20           * classloader is still set to the rest bundle (which has access to
21           * {@link com.sun.ws.rs.ext.RuntimeDelegateImpl}.
22           * </p>
23           * <p>
24           * If we wait for it to lazily initialize itself, we can (and in fact,
25           * we did) run into trouble when
26           * {@link #getUrlFor(java.net.URI, Class)} is called by a different
27           * plugin. In that scenario, by the time the caller then invokes a
28           * method on the returned cglib-generated proxy instance which
29           * triggers initialization of the jsr311 library, we get a
30           * {@link ClassNotFoundException} because
31           * {@link javax.ws.rs.ext.FactoryFinder#newInstance(String, ClassLoader)}
32           * relies on the context classloader to have access to
33           * {@link com.sun.ws.rs.ext.RuntimeDelegateImpl}, which it doesn't
34           * because that invocation is performed inside the calling plugin.
35           * </p>
36           * <p>
37           * It seems likely the above problem only applies to jsr311-1.0 (the
38           * one atlassian.jersey-library ships with) and is fixed in 1.1.1, so
39           * once we upgrade jersey, we should be able to get rid of this hack.
40           */
41          RuntimeDelegate.getInstance();
42      }
43  
44      public URI getURI(Response resource) {
45          if (resource instanceof GeneratedURIResponse) {
46              return ((GeneratedURIResponse) resource).getURI();
47          } else {
48              throw new IllegalArgumentException("Supplied response is not a generated one");
49          }
50      }
51  
52      public <T> T getUrlFor(URI baseUri, Class<T> resourceClass) {
53          Assert.notNull(resourceClass, "resourceClass cannot be null");
54          Assert.notNull(baseUri, "baseUri cannot be null");
55          return ProxyUtils.create(resourceClass, new ResourcePathUrlInvokable(resourceClass, baseUri));
56      }
57  }