/resteasy-2.3.2.Final/resteasy-jaxrs/src/main/java/org/jboss/resteasy/client/core/extractors/ResponseObjectEntityExtractorFactory.java

# · Java · 258 lines · 224 code · 25 blank · 9 comment · 43 complexity · ae5a0330fb10023d3b90810ba3323e51 MD5 · raw file

  1. package org.jboss.resteasy.client.core.extractors;
  2. import org.jboss.resteasy.annotations.Body;
  3. import org.jboss.resteasy.annotations.LinkHeaderParam;
  4. import org.jboss.resteasy.annotations.Status;
  5. import org.jboss.resteasy.client.ClientExecutor;
  6. import org.jboss.resteasy.client.ClientRequest;
  7. import org.jboss.resteasy.client.ProxyFactory;
  8. import org.jboss.resteasy.spi.Link;
  9. import org.jboss.resteasy.spi.LinkHeader;
  10. import org.jboss.resteasy.spi.ResteasyProviderFactory;
  11. import org.jboss.resteasy.util.IsHttpMethod;
  12. import javax.ws.rs.HeaderParam;
  13. import javax.ws.rs.core.Response;
  14. import java.lang.reflect.Method;
  15. import java.net.MalformedURLException;
  16. import java.net.URI;
  17. import java.net.URISyntaxException;
  18. import java.net.URL;
  19. import java.util.Set;
  20. /**
  21. * This class represents the method level creation of a "rich response object"
  22. * that has the @ResponseObject annotation. These EntityExtractors will be used
  23. * to implment methods of ResponseObject via ResponseObjectEntityExtractor
  24. *
  25. * @author <a href="mailto:sduskis@gmail.com">Solomon Duskis</a>
  26. * @version $Revision: 1 $
  27. * @see EntityExtractor, ResponseObjectEntityExtractor
  28. */
  29. public class ResponseObjectEntityExtractorFactory extends DefaultEntityExtractorFactory
  30. {
  31. @SuppressWarnings("unchecked")
  32. public EntityExtractor createExtractor(final Method method)
  33. {
  34. final Class<?> returnType = method.getReturnType();
  35. if (method.isAnnotationPresent(Status.class))
  36. {
  37. if (returnType == Integer.class || returnType == int.class)
  38. {
  39. return new EntityExtractor<Integer>()
  40. {
  41. public Integer extractEntity(ClientRequestContext context, Object... args)
  42. {
  43. return context.getClientResponse().getStatus();
  44. }
  45. };
  46. }
  47. else if (returnType == Response.Status.class)
  48. {
  49. return createStatusExtractor(false);
  50. }
  51. }
  52. if (method.isAnnotationPresent(Body.class))
  53. {
  54. return new BodyEntityExtractor(method);
  55. }
  56. final HeaderParam headerParam = method.getAnnotation(HeaderParam.class);
  57. if (headerParam != null)
  58. {
  59. return new EntityExtractor()
  60. {
  61. public Object extractEntity(ClientRequestContext context, Object... args)
  62. {
  63. return context.getClientResponse().getHeaders().getFirst(headerParam.value());
  64. }
  65. };
  66. }
  67. final LinkHeaderParam link = method.getAnnotation(LinkHeaderParam.class);
  68. if (link != null)
  69. {
  70. return processLinkHeader(method, returnType, link);
  71. }
  72. if (returnType == ClientRequest.class)
  73. {
  74. return new EntityExtractor()
  75. {
  76. public Object extractEntity(ClientRequestContext context, Object... args)
  77. {
  78. return context.getRequest();
  79. }
  80. };
  81. }
  82. if (Response.class.isAssignableFrom(returnType))
  83. {
  84. return createResponseTypeEntityExtractor(method);
  85. }
  86. if (returnType == LinkHeader.class)
  87. {
  88. return new EntityExtractor()
  89. {
  90. public Object extractEntity(ClientRequestContext context, Object... args)
  91. {
  92. return context.getClientResponse().getLinkHeader();
  93. }
  94. };
  95. }
  96. return null;
  97. }
  98. private EntityExtractor processLinkHeader(final Method method, final Class<?> returnType,
  99. final LinkHeaderParam link)
  100. {
  101. if ("".equals(link.rel()) && "".equals(link.title()))
  102. {
  103. throw new RuntimeException(String.format(
  104. "You must set either LinkHeaderParam.rel() or LinkHeaderParam.title() for on %s.%s",
  105. method.getClass().getName(), method.getName()));
  106. }
  107. if (!"".equals(link.rel()) && !"".equals(link.title()))
  108. {
  109. throw new RuntimeException(
  110. String
  111. .format(
  112. "You can only set one of LinkHeaderParam.rel() and LinkHeaderParam.title() for on %s.%s",
  113. method.getClass().getName(), method.getName()));
  114. }
  115. if (returnType == Link.class)
  116. {
  117. return new EntityExtractor()
  118. {
  119. public Object extractEntity(ClientRequestContext context, Object... args)
  120. {
  121. return getLink(link, context);
  122. }
  123. };
  124. }
  125. if (isInvokerMethod(method))
  126. {
  127. return new EntityExtractor()
  128. {
  129. public Object extractEntity(ClientRequestContext context, Object... args)
  130. {
  131. URI uri = getURI(method, link, context);
  132. if (uri == null)
  133. return null;
  134. ClientRequest request = context.getRequest();
  135. EntityExtractorFactory extractor = context.getExtractorFactory();
  136. ResteasyProviderFactory provider = request.getProviderFactory();
  137. ClientExecutor executor = request.getExecutor();
  138. return ProxyFactory.createClientInvoker(method.getClass(), method, uri,
  139. executor, provider, extractor).invoke(args);
  140. }
  141. };
  142. }
  143. if (returnType == String.class)
  144. {
  145. return new EntityExtractor<String>()
  146. {
  147. public String extractEntity(ClientRequestContext context, Object... args)
  148. {
  149. Link link2 = getLink(link, context);
  150. return link2 == null ? null : link2.getHref();
  151. }
  152. };
  153. }
  154. if (returnType == URL.class)
  155. {
  156. return new EntityExtractor<URL>()
  157. {
  158. public URL extractEntity(ClientRequestContext context, Object... args)
  159. {
  160. return getURL(method, link, context);
  161. }
  162. };
  163. }
  164. if (returnType == URI.class)
  165. {
  166. return new EntityExtractor<URI>()
  167. {
  168. public URI extractEntity(ClientRequestContext context, Object... args)
  169. {
  170. return getURI(method, link, context);
  171. }
  172. };
  173. }
  174. if (returnType.equals(ClientRequest.class))
  175. {
  176. return new EntityExtractor<ClientRequest>()
  177. {
  178. public ClientRequest extractEntity(ClientRequestContext context, Object... args)
  179. {
  180. URI uri = getURI(method, link, context);
  181. return uri == null ? null : context.getRequest().createSubsequentRequest(uri);
  182. }
  183. };
  184. }
  185. return null;
  186. }
  187. private static boolean isInvokerMethod(Method method)
  188. {
  189. Set<String> httpMethods = IsHttpMethod.getHttpMethods(method);
  190. return httpMethods != null && httpMethods.size() == 1;
  191. }
  192. private Link getLink(final LinkHeaderParam link, ClientRequestContext context)
  193. {
  194. LinkHeader linkHeader = context.getClientResponse().getLinkHeader();
  195. if (!"".equals(link.rel()))
  196. return linkHeader.getLinkByRelationship(link.rel());
  197. else
  198. return linkHeader.getLinkByTitle(link.title());
  199. }
  200. private URI getURI(final Method method, Link link)
  201. {
  202. if (link == null)
  203. {
  204. return null;
  205. }
  206. try
  207. {
  208. return new URI(link.getHref());
  209. }
  210. catch (URISyntaxException e)
  211. {
  212. throw new RuntimeException(String.format("Could not create a URI for %s in %s.%s", link
  213. .getHref(), method.getClass().getName(), method.getName()), e);
  214. }
  215. }
  216. private URI getURI(final Method method, final LinkHeaderParam link, ClientRequestContext context)
  217. {
  218. return getURI(method, getLink(link, context));
  219. }
  220. private URL getURL(final Method method, final LinkHeaderParam link, ClientRequestContext context)
  221. {
  222. URI uri = getURI(method, link, context);
  223. try
  224. {
  225. return uri == null ? null : uri.toURL();
  226. }
  227. catch (MalformedURLException e)
  228. {
  229. throw new RuntimeException(String.format("Could not create a URL for %s in %s.%s", uri
  230. .toASCIIString(), method.getClass().getName(), method.getName()), e);
  231. }
  232. }
  233. }