1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.jclouds.rest.internal;
20
21 import static com.google.common.collect.Sets.difference;
22 import static org.jclouds.rest.internal.RestAnnotationProcessor.delegationMap;
23 import static org.jclouds.rest.internal.RestAnnotationProcessor.getHttpMethods;
24 import static org.jclouds.rest.internal.RestAnnotationProcessor.methodToIndexOfParamToBinderParamAnnotation;
25 import static org.jclouds.rest.internal.RestAnnotationProcessor.methodToIndexOfParamToEndpointAnnotations;
26 import static org.jclouds.rest.internal.RestAnnotationProcessor.methodToIndexOfParamToEndpointParamAnnotations;
27 import static org.jclouds.rest.internal.RestAnnotationProcessor.methodToIndexOfParamToFormParamAnnotations;
28 import static org.jclouds.rest.internal.RestAnnotationProcessor.methodToIndexOfParamToHeaderParamAnnotations;
29 import static org.jclouds.rest.internal.RestAnnotationProcessor.methodToIndexOfParamToMatrixParamAnnotations;
30 import static org.jclouds.rest.internal.RestAnnotationProcessor.methodToIndexOfParamToParamParserAnnotations;
31 import static org.jclouds.rest.internal.RestAnnotationProcessor.methodToIndexOfParamToPartParamAnnotations;
32 import static org.jclouds.rest.internal.RestAnnotationProcessor.methodToIndexOfParamToPathParamAnnotations;
33 import static org.jclouds.rest.internal.RestAnnotationProcessor.methodToIndexOfParamToPostParamAnnotations;
34 import static org.jclouds.rest.internal.RestAnnotationProcessor.methodToIndexOfParamToQueryParamAnnotations;
35 import static org.jclouds.rest.internal.RestAnnotationProcessor.methodToIndexOfParamToWrapWithAnnotation;
36 import static org.jclouds.rest.internal.RestAnnotationProcessor.methodToIndexesOfOptions;
37
38 import java.lang.reflect.Method;
39 import java.util.concurrent.ExecutionException;
40
41 import javax.annotation.Resource;
42 import javax.inject.Named;
43 import javax.inject.Singleton;
44 import javax.ws.rs.Path;
45 import javax.ws.rs.PathParam;
46
47 import org.jclouds.http.HttpRequest;
48 import org.jclouds.logging.Logger;
49 import org.jclouds.rest.annotations.Delegate;
50 import org.jclouds.rest.internal.RestAnnotationProcessor.MethodKey;
51
52 import com.google.common.cache.CacheLoader;
53 import com.google.common.collect.ImmutableSet;
54 import com.google.common.collect.Multimap;
55 import com.google.inject.Inject;
56 import com.google.inject.Injector;
57 import com.google.inject.Key;
58 import com.google.inject.Provides;
59
60
61
62
63
64
65
66 @Singleton
67 public class SeedAnnotationCache extends CacheLoader<Class<?>, Boolean> {
68 @Resource
69 protected Logger logger = Logger.NULL;
70
71 protected final Multimap<String, String> constants;
72 protected final Injector injector;
73
74 @Inject
75 public SeedAnnotationCache(Injector injector, @Named("CONSTANTS") Multimap<String, String> constants) {
76 this.injector = injector;
77 this.constants = constants;
78 }
79
80 public void bindConstant(Method method) {
81 String key = method.getAnnotation(PathParam.class).value();
82 String value = injector.getInstance(Key.get(String.class, method.getAnnotation(Named.class)));
83 constants.put(key, value);
84 }
85
86 @Override
87 public Boolean load(Class<?> declaring) throws ExecutionException {
88 for (Method method : difference(ImmutableSet.copyOf(declaring.getMethods()), ImmutableSet.copyOf(Object.class
89 .getMethods()))) {
90 if (isHttpMethod(method) || method.isAnnotationPresent(Delegate.class)) {
91 for (int index = 0; index < method.getParameterTypes().length; index++) {
92 methodToIndexOfParamToBinderParamAnnotation.get(method).get(index);
93 methodToIndexOfParamToWrapWithAnnotation.get(method).get(index);
94 methodToIndexOfParamToHeaderParamAnnotations.get(method).get(index);
95 methodToIndexOfParamToMatrixParamAnnotations.get(method).get(index);
96 methodToIndexOfParamToFormParamAnnotations.get(method).get(index);
97 methodToIndexOfParamToQueryParamAnnotations.get(method).get(index);
98 methodToIndexOfParamToEndpointAnnotations.get(method).get(index);
99 methodToIndexOfParamToEndpointParamAnnotations.get(method).get(index);
100 methodToIndexOfParamToPathParamAnnotations.get(method).get(index);
101 methodToIndexOfParamToPostParamAnnotations.get(method).get(index);
102 methodToIndexOfParamToParamParserAnnotations.get(method).get(index);
103 methodToIndexOfParamToPartParamAnnotations.get(method).get(index);
104 methodToIndexesOfOptions.get(method);
105 }
106 delegationMap.put(new MethodKey(method), method);
107 } else if (isConstantDeclaration(method)) {
108 bindConstant(method);
109 } else if (!method.getDeclaringClass().equals(declaring)) {
110 logger.trace("skipping potentially overridden method %s", method);
111 } else if (method.isAnnotationPresent(Provides.class)) {
112 logger.trace("skipping provider method %s", method);
113 } else {
114 logger.trace("Method is not annotated as either http or constant: %s", method);
115 }
116 }
117 return true;
118 }
119
120 public static boolean isHttpMethod(Method method) {
121 return method.isAnnotationPresent(Path.class) || getHttpMethods(method) != null
122 || ImmutableSet.copyOf(method.getParameterTypes()).contains(HttpRequest.class);
123 }
124
125 public static boolean isConstantDeclaration(Method method) {
126 return method.isAnnotationPresent(PathParam.class) && method.isAnnotationPresent(Named.class);
127 }
128 }