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