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
40 import javax.annotation.Resource;
41 import javax.inject.Named;
42 import javax.inject.Singleton;
43 import javax.ws.rs.Path;
44 import javax.ws.rs.PathParam;
45
46 import org.jclouds.http.HttpRequest;
47 import org.jclouds.logging.Logger;
48 import org.jclouds.rest.annotations.Delegate;
49 import org.jclouds.rest.internal.RestAnnotationProcessor.MethodKey;
50
51 import com.google.common.base.Function;
52 import com.google.common.collect.ImmutableSet;
53 import com.google.common.collect.Multimap;
54 import com.google.inject.Inject;
55 import com.google.inject.Injector;
56 import com.google.inject.Key;
57 import com.google.inject.Provides;
58
59
60
61
62
63
64
65 @Singleton
66 public class SeedAnnotationCache implements Function<Class<?>, Boolean> {
67 @Resource
68 protected Logger logger = Logger.NULL;
69
70 protected final Multimap<String, String> constants;
71 protected final Injector injector;
72
73 @Inject
74 public SeedAnnotationCache(Injector injector, @Named("CONSTANTS") Multimap<String, String> constants) {
75 this.injector = injector;
76 this.constants = constants;
77 }
78
79 public void bindConstant(Method method) {
80 String key = method.getAnnotation(PathParam.class).value();
81 String value = injector.getInstance(Key.get(String.class, method.getAnnotation(Named.class)));
82 constants.put(key, value);
83 }
84
85 public Boolean apply(Class<?> declaring) {
86 for (Method method : difference(ImmutableSet.copyOf(declaring.getMethods()), ImmutableSet.copyOf(Object.class
87 .getMethods()))) {
88 if (isHttpMethod(method) || method.isAnnotationPresent(Delegate.class)) {
89 for (int index = 0; index < method.getParameterTypes().length; index++) {
90 methodToIndexOfParamToBinderParamAnnotation.get(method).get(index);
91 methodToIndexOfParamToWrapWithAnnotation.get(method).get(index);
92 methodToIndexOfParamToHeaderParamAnnotations.get(method).get(index);
93 methodToIndexOfParamToMatrixParamAnnotations.get(method).get(index);
94 methodToIndexOfParamToFormParamAnnotations.get(method).get(index);
95 methodToIndexOfParamToQueryParamAnnotations.get(method).get(index);
96 methodToIndexOfParamToEndpointAnnotations.get(method).get(index);
97 methodToIndexOfParamToEndpointParamAnnotations.get(method).get(index);
98 methodToIndexOfParamToPathParamAnnotations.get(method).get(index);
99 methodToIndexOfParamToPostParamAnnotations.get(method).get(index);
100 methodToIndexOfParamToParamParserAnnotations.get(method).get(index);
101 methodToIndexOfParamToPartParamAnnotations.get(method).get(index);
102 methodToIndexesOfOptions.get(method);
103 }
104 delegationMap.put(new MethodKey(method), method);
105 } else if (isConstantDeclaration(method)) {
106 bindConstant(method);
107 } else if (!method.getDeclaringClass().equals(declaring)) {
108 logger.trace("skipping potentially overridden method %s", method);
109 } else if (method.isAnnotationPresent(Provides.class)) {
110 logger.trace("skipping provider method %s", method);
111 } else {
112 logger.trace("Method is not annotated as either http or constant: %s", method);
113 }
114 }
115 return true;
116 }
117
118 public static boolean isHttpMethod(Method method) {
119 return method.isAnnotationPresent(Path.class) || getHttpMethods(method) != null
120 || ImmutableSet.copyOf(method.getParameterTypes()).contains(HttpRequest.class);
121 }
122
123 public static boolean isConstantDeclaration(Method method) {
124 return method.isAnnotationPresent(PathParam.class) && method.isAnnotationPresent(Named.class);
125 }
126 }