mirror of https://github.com/apache/jclouds.git
centralize construction of invokables
This commit is contained in:
parent
fe220e5105
commit
58f0f577d0
|
@ -42,7 +42,7 @@ import static org.jclouds.Constants.PROPERTY_ENDPOINT;
|
|||
import static org.jclouds.Constants.PROPERTY_IDENTITY;
|
||||
import static org.jclouds.Constants.PROPERTY_ISO3166_CODES;
|
||||
import static org.jclouds.Constants.PROPERTY_PROVIDER;
|
||||
import static org.jclouds.reflect.Reflection2.typeTokenOf;
|
||||
import static org.jclouds.reflect.Reflection2.typeToken;
|
||||
import static org.jclouds.util.Throwables2.propagateAuthorizationOrOriginalException;
|
||||
|
||||
import java.util.List;
|
||||
|
@ -491,7 +491,7 @@ public class ContextBuilder {
|
|||
// TODO: move this up
|
||||
if (apiMetadata instanceof RestApiMetadata) {
|
||||
RestApiMetadata rest = RestApiMetadata.class.cast(apiMetadata);
|
||||
modules.add(new RestClientModule(typeTokenOf(rest.getApi()), typeTokenOf(rest.getAsyncApi())));
|
||||
modules.add(new RestClientModule(typeToken(rest.getApi()), typeToken(rest.getAsyncApi())));
|
||||
} else {
|
||||
modules.add(new RestModule());
|
||||
}
|
||||
|
@ -568,7 +568,7 @@ public class ContextBuilder {
|
|||
* @see #buildView(TypeToken)
|
||||
*/
|
||||
public <V extends View> V buildView(Class<V> viewType) {
|
||||
return buildView(typeTokenOf(viewType));
|
||||
return buildView(typeToken(viewType));
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -21,7 +21,7 @@ package org.jclouds.apis;
|
|||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
import static com.google.common.collect.Iterables.filter;
|
||||
import static com.google.common.collect.Iterables.find;
|
||||
import static org.jclouds.reflect.Reflection2.typeTokenOf;
|
||||
import static org.jclouds.reflect.Reflection2.typeToken;
|
||||
|
||||
import java.util.NoSuchElementException;
|
||||
import java.util.ServiceLoader;
|
||||
|
@ -116,7 +116,7 @@ public class Apis {
|
|||
}
|
||||
|
||||
public static Iterable<ApiMetadata> viewableAs(Class<? extends View> type) {
|
||||
return filter(all(), ApiPredicates.viewableAs(typeTokenOf(type)));
|
||||
return filter(all(), ApiPredicates.viewableAs(typeToken(type)));
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -32,7 +32,7 @@ import static org.jclouds.Constants.PROPERTY_SCHEDULER_THREADS;
|
|||
import static org.jclouds.Constants.PROPERTY_SESSION_INTERVAL;
|
||||
import static org.jclouds.Constants.PROPERTY_SO_TIMEOUT;
|
||||
import static org.jclouds.Constants.PROPERTY_USER_THREADS;
|
||||
import static org.jclouds.reflect.Reflection2.typeTokenOf;
|
||||
import static org.jclouds.reflect.Reflection2.typeToken;
|
||||
|
||||
import java.net.URI;
|
||||
import java.util.Properties;
|
||||
|
@ -93,7 +93,7 @@ public abstract class BaseApiMetadata implements ApiMetadata {
|
|||
private Optional<String> defaultCredential = Optional.absent();
|
||||
private Properties defaultProperties = BaseApiMetadata.defaultProperties();
|
||||
private URI documentation;
|
||||
private TypeToken<? extends Context> context = typeTokenOf(Context.class);
|
||||
private TypeToken<? extends Context> context = typeToken(Context.class);
|
||||
private Set<Class<? extends Module>> defaultModules = ImmutableSet.of();
|
||||
|
||||
/**
|
||||
|
@ -119,7 +119,7 @@ public abstract class BaseApiMetadata implements ApiMetadata {
|
|||
*/
|
||||
@Override
|
||||
public T view(Class<? extends View> view) {
|
||||
return view(typeTokenOf(checkNotNull(view, "view")));
|
||||
return view(typeToken(checkNotNull(view, "view")));
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -17,10 +17,9 @@
|
|||
* under the License.
|
||||
*/
|
||||
package org.jclouds.config;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkArgument;
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
import static org.jclouds.reflect.Reflection2.typeTokenOf;
|
||||
import static org.jclouds.reflect.Reflection2.typeToken;
|
||||
|
||||
import org.jclouds.rest.RestApiMetadata;
|
||||
import org.jclouds.rest.RestContext;
|
||||
|
@ -50,8 +49,8 @@ public class BindRestContextWithWildcardExtendsExplicitAndRawType extends Abstra
|
|||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
protected void configure() {
|
||||
TypeToken<?> concreteType = BaseRestApiMetadata.contextToken(typeTokenOf(restApiMetadata.getApi()), TypeToken
|
||||
.of(restApiMetadata.getAsyncApi()));
|
||||
TypeToken<?> concreteType = BaseRestApiMetadata.contextToken(typeToken(restApiMetadata.getApi()),
|
||||
typeToken(restApiMetadata.getAsyncApi()));
|
||||
// bind explicit type
|
||||
bind(TypeLiteral.get(concreteType.getType())).to(
|
||||
TypeLiteral.class.cast(TypeLiteral.get(Types.newParameterizedType(RestContextImpl.class,
|
||||
|
|
|
@ -17,10 +17,9 @@
|
|||
* under the License.
|
||||
*/
|
||||
package org.jclouds.providers;
|
||||
|
||||
import static com.google.common.collect.Iterables.filter;
|
||||
import static com.google.common.collect.Iterables.find;
|
||||
import static org.jclouds.reflect.Reflection2.typeTokenOf;
|
||||
import static org.jclouds.reflect.Reflection2.typeToken;
|
||||
|
||||
import java.util.NoSuchElementException;
|
||||
import java.util.ServiceLoader;
|
||||
|
@ -117,7 +116,7 @@ public class Providers {
|
|||
}
|
||||
|
||||
public static Iterable<ProviderMetadata> viewableAs(Class<? extends View> viewableAs) {
|
||||
return filter(all(), ProviderPredicates.viewableAs(typeTokenOf(viewableAs)));
|
||||
return filter(all(), ProviderPredicates.viewableAs(typeToken(viewableAs)));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -179,7 +178,7 @@ public class Providers {
|
|||
|
||||
public static Iterable<ProviderMetadata> boundedByIso3166Code(String iso3166Code,
|
||||
Class<? extends View> viewableAs) {
|
||||
return boundedByIso3166Code(iso3166Code, typeTokenOf(viewableAs));
|
||||
return boundedByIso3166Code(iso3166Code, typeToken(viewableAs));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -215,6 +214,6 @@ public class Providers {
|
|||
|
||||
public static Iterable<ProviderMetadata> collocatedWith(ProviderMetadata providerMetadata,
|
||||
Class<? extends View> viewableAs) {
|
||||
return collocatedWith(providerMetadata, typeTokenOf(viewableAs));
|
||||
return collocatedWith(providerMetadata, typeToken(viewableAs));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -24,7 +24,8 @@ import static com.google.common.base.Preconditions.checkNotNull;
|
|||
import static com.google.common.base.Predicates.notNull;
|
||||
import static com.google.common.base.Throwables.propagate;
|
||||
import static com.google.common.collect.Iterables.all;
|
||||
import static org.jclouds.reflect.Reflection2.typeTokenOf;
|
||||
import static org.jclouds.reflect.Reflection2.method;
|
||||
import static org.jclouds.reflect.Reflection2.typeToken;
|
||||
import static org.jclouds.util.Throwables2.propagateIfPossible;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
|
@ -84,8 +85,7 @@ public final class FunctionalReflection {
|
|||
|
||||
public static <T> T newProxy(Class<T> enclosingType, Function<Invocation, Object> invocationFunction) {
|
||||
checkNotNull(invocationFunction, "invocationFunction");
|
||||
return newProxy(enclosingType,
|
||||
new FunctionalInvocationHandler<T>(typeTokenOf(enclosingType), invocationFunction));
|
||||
return newProxy(enclosingType, new FunctionalInvocationHandler<T>(typeToken(enclosingType), invocationFunction));
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
|
@ -113,7 +113,7 @@ public final class FunctionalReflection {
|
|||
args = ImmutableList.copyOf(args);
|
||||
else
|
||||
args = Collections.unmodifiableList(args);
|
||||
Invokable<?, Object> invokable = enclosingType.method(invoked);
|
||||
Invokable<T, Object> invokable = method(enclosingType, invoked);
|
||||
Invocation invocation = Invocation.create(invokable, args);
|
||||
try {
|
||||
return invocationFunction.apply(invocation);
|
||||
|
|
|
@ -19,65 +19,196 @@
|
|||
package org.jclouds.reflect;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
import static com.google.common.collect.Iterables.toArray;
|
||||
|
||||
import java.lang.reflect.Type;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import com.google.common.annotations.Beta;
|
||||
import com.google.common.base.Function;
|
||||
import com.google.common.base.Objects;
|
||||
import com.google.common.cache.CacheBuilder;
|
||||
import com.google.common.cache.CacheLoader;
|
||||
import com.google.common.cache.LoadingCache;
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import com.google.common.collect.ImmutableMap.Builder;
|
||||
import com.google.common.reflect.Invokable;
|
||||
import com.google.common.reflect.TypeToken;
|
||||
|
||||
/**
|
||||
* Invokable utilities
|
||||
* Utilities that allow access to {@link Invokable}s with {@link Invokable#getOwnerType() owner types}.
|
||||
*
|
||||
* @since 1.6
|
||||
*/
|
||||
@Beta
|
||||
public final class Reflection2 {
|
||||
private static final LoadingCache<Class<?>, TypeToken<?>> typeTokenForClass = CacheBuilder.newBuilder().build(
|
||||
new CacheLoader<Class<?>, TypeToken<?>>() {
|
||||
public TypeToken<?> load(final Class<?> key) throws Exception {
|
||||
return TypeToken.of(key);
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* Cache of type tokens for the supplied class.
|
||||
*/
|
||||
public static Function<Class<?>, TypeToken<?>> typeTokenForClass() {
|
||||
return typeTokenForClass;
|
||||
}
|
||||
|
||||
/**
|
||||
* Cache of type tokens for the supplied class.
|
||||
* gets a {@link TypeToken} for the given class.
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public static <T> TypeToken<T> typeTokenOf(Class<T> in) {
|
||||
public static <T> TypeToken<T> typeToken(Class<T> in) {
|
||||
return (TypeToken<T>) typeTokenForClass.apply(checkNotNull(in, "class"));
|
||||
}
|
||||
|
||||
private static final LoadingCache<Type, TypeToken<?>> typeTokenForType = CacheBuilder.newBuilder().build(
|
||||
new CacheLoader<Type, TypeToken<?>>() {
|
||||
public TypeToken<?> load(final Type key) throws Exception {
|
||||
/**
|
||||
* returns an {@link Invokable} object that links the {@code method} to its owner.
|
||||
*
|
||||
* @param ownerType
|
||||
* corresponds to {@link Invokable#getOwnerType()}
|
||||
* @param method
|
||||
* present in {@code ownerType}
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public static <T, R> Invokable<T, R> method(TypeToken<T> ownerType, Method method) {
|
||||
return (Invokable<T, R>) methods.apply(new TypeTokenAndMethod(ownerType, method));
|
||||
}
|
||||
|
||||
/**
|
||||
* returns an {@link Invokable} object that reflects a method present in the {@link TypeToken} type.
|
||||
*
|
||||
* @param ownerType
|
||||
* corresponds to {@link Invokable#getOwnerType()}
|
||||
* @param parameterTypes
|
||||
* corresponds to {@link Method#getParameterTypes()}
|
||||
*
|
||||
* @throws IllegalArgumentException
|
||||
* if the method doesn't exist or a security exception occurred
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public static <T, R> Invokable<T, R> method(Class<T> ownerType, String name, Class<?>... parameterTypes) {
|
||||
return (Invokable<T, R>) methodForArgs.apply(new TypeTokenNameAndParameterTypes(typeToken(ownerType), name,
|
||||
parameterTypes));
|
||||
}
|
||||
|
||||
/**
|
||||
* return all methods present in the class as {@link Invokable}s.
|
||||
*
|
||||
* @param ownerType
|
||||
* corresponds to {@link Invokable#getOwnerType()}
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public static <T> Collection<Invokable<T, Object>> methods(Class<T> ownerType) {
|
||||
return Collection.class.cast(methodsForTypeToken.apply(typeToken(ownerType)).values());
|
||||
}
|
||||
|
||||
private static final LoadingCache<TypeTokenAndMethod, Invokable<?, ?>> methods = CacheBuilder.newBuilder().build(
|
||||
new CacheLoader<TypeTokenAndMethod, Invokable<?, ?>>() {
|
||||
public Invokable<?, ?> load(TypeTokenAndMethod key) {
|
||||
return key.type.method(key.method);
|
||||
}
|
||||
});
|
||||
|
||||
private static class TypeTokenAndMethod {
|
||||
|
||||
protected final TypeToken<?> type;
|
||||
protected final Method method;
|
||||
|
||||
public TypeTokenAndMethod(TypeToken<?> type, Method method) {
|
||||
this.type = checkNotNull(type, "type");
|
||||
this.method = checkNotNull(method, "method");
|
||||
}
|
||||
|
||||
public int hashCode() {
|
||||
return Objects.hashCode(type, method);
|
||||
}
|
||||
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj)
|
||||
return true;
|
||||
if (obj == null || getClass() != obj.getClass())
|
||||
return false;
|
||||
TypeTokenAndMethod that = TypeTokenAndMethod.class.cast(obj);
|
||||
return Objects.equal(this.type, that.type) && Objects.equal(this.method, that.method);
|
||||
}
|
||||
}
|
||||
|
||||
private static final LoadingCache<Class<?>, TypeToken<?>> typeTokenForClass = CacheBuilder.newBuilder().build(
|
||||
new CacheLoader<Class<?>, TypeToken<?>>() {
|
||||
public TypeToken<?> load(final Class<?> key) {
|
||||
return TypeToken.of(key);
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* Cache of type tokens for the supplied class.
|
||||
*/
|
||||
public static Function<Type, TypeToken<?>> typeTokenForType() {
|
||||
return typeTokenForType;
|
||||
private static class TypeTokenAndParameterTypes {
|
||||
|
||||
protected final TypeToken<?> type;
|
||||
protected final List<Class<?>> parameterTypes;
|
||||
|
||||
public TypeTokenAndParameterTypes(TypeToken<?> type, Class<?>... parameterTypes) {
|
||||
this.type = checkNotNull(type, "type");
|
||||
this.parameterTypes = Arrays.asList(checkNotNull(parameterTypes, "parameterTypes"));
|
||||
}
|
||||
|
||||
public int hashCode() {
|
||||
return Objects.hashCode(type, parameterTypes);
|
||||
}
|
||||
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj)
|
||||
return true;
|
||||
if (obj == null || getClass() != obj.getClass())
|
||||
return false;
|
||||
TypeTokenAndParameterTypes that = TypeTokenAndParameterTypes.class.cast(obj);
|
||||
return Objects.equal(this.type, that.type) && Objects.equal(this.parameterTypes, that.parameterTypes);
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return Objects.toStringHelper("").add("type", type).add("parameterTypes", parameterTypes).toString();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Cache of type tokens for the supplied type.
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public static <T> TypeToken<T> typeTokenOf(Type in) {
|
||||
return (TypeToken<T>) typeTokenForType.apply(checkNotNull(in, "class"));
|
||||
private static final LoadingCache<TypeTokenNameAndParameterTypes, Invokable<?, ?>> methodForArgs = CacheBuilder
|
||||
.newBuilder().build(new CacheLoader<TypeTokenNameAndParameterTypes, Invokable<?, ?>>() {
|
||||
public Invokable<?, ?> load(final TypeTokenNameAndParameterTypes key) {
|
||||
try {
|
||||
Method method = key.type.getRawType().getMethod(key.name, toArray(key.parameterTypes, Class.class));
|
||||
return methods.apply(new TypeTokenAndMethod(key.type, method));
|
||||
} catch (SecurityException e) {
|
||||
throw new IllegalArgumentException(e.getMessage() + " getting method " + key.toString(), e);
|
||||
} catch (NoSuchMethodException e) {
|
||||
throw new IllegalArgumentException("no such method " + key.toString(), e);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
private static class TypeTokenNameAndParameterTypes extends TypeTokenAndParameterTypes {
|
||||
|
||||
private final String name;
|
||||
|
||||
public TypeTokenNameAndParameterTypes(TypeToken<?> type, String name, Class<?>... parameterTypes) {
|
||||
super(type, parameterTypes);
|
||||
this.name = checkNotNull(name, "name");
|
||||
}
|
||||
|
||||
public int hashCode() {
|
||||
return Objects.hashCode(super.hashCode(), name);
|
||||
}
|
||||
|
||||
public boolean equals(Object obj) {
|
||||
if (super.equals(obj)) {
|
||||
TypeTokenNameAndParameterTypes that = TypeTokenNameAndParameterTypes.class.cast(obj);
|
||||
return name.equals(that.name);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return Objects.toStringHelper("").add("type", type).add("name", name).add("parameterTypes", parameterTypes)
|
||||
.toString();
|
||||
}
|
||||
}
|
||||
|
||||
private static final LoadingCache<TypeToken<?>, Map<Method, Invokable<?, ?>>> methodsForTypeToken = CacheBuilder
|
||||
.newBuilder().build(new CacheLoader<TypeToken<?>, Map<Method, Invokable<?, ?>>>() {
|
||||
public Map<Method, Invokable<?, ?>> load(final TypeToken<?> key) {
|
||||
Builder<Method, Invokable<?, ?>> builder = ImmutableMap.<Method, Invokable<?, ?>> builder();
|
||||
for (Method method : key.getRawType().getMethods())
|
||||
builder.put(method, method(key, method));
|
||||
return builder.build();
|
||||
}
|
||||
});
|
||||
|
||||
}
|
|
@ -18,7 +18,6 @@
|
|||
*/
|
||||
package org.jclouds.rest.config;
|
||||
|
||||
import static org.jclouds.reflect.Reflection2.typeTokenOf;
|
||||
|
||||
import java.lang.reflect.Proxy;
|
||||
|
||||
|
@ -47,7 +46,7 @@ public class CallGetOnFuturesProvider<S, A> implements Provider<S> {
|
|||
Class<A> asyncApiType) {
|
||||
this.syncInvoker = syncInvoker;
|
||||
this.apiType = apiType;
|
||||
RestModule.putInvokables(typeTokenOf(apiType), typeTokenOf(asyncApiType), invokables);
|
||||
RestModule.putInvokables(apiType, asyncApiType, invokables);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
|
|
|
@ -18,7 +18,6 @@
|
|||
*/
|
||||
package org.jclouds.rest.config;
|
||||
|
||||
import static org.jclouds.reflect.Reflection2.typeTokenOf;
|
||||
|
||||
import java.lang.reflect.Proxy;
|
||||
|
||||
|
@ -46,7 +45,7 @@ public class HttpApiProvider<S, A> implements Provider<S> {
|
|||
DelegatesToInvocationFunction<S, InvokeHttpMethod> httpInvoker, Class<S> apiType, Class<A> asyncApiType) {
|
||||
this.httpInvoker = httpInvoker;
|
||||
this.apiType = apiType;
|
||||
RestModule.putInvokables(typeTokenOf(apiType), typeTokenOf(asyncApiType), invokables);
|
||||
RestModule.putInvokables(apiType, asyncApiType, invokables);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
|
|
|
@ -19,18 +19,21 @@
|
|||
package org.jclouds.rest.config;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkArgument;
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
import static com.google.common.base.Throwables.propagate;
|
||||
import static com.google.common.collect.Iterables.toArray;
|
||||
import static com.google.common.collect.Iterables.transform;
|
||||
import static com.google.common.collect.Maps.transformValues;
|
||||
import static com.google.common.util.concurrent.Atomics.newReference;
|
||||
import static org.jclouds.Constants.PROPERTY_TIMEOUTS_PREFIX;
|
||||
import static org.jclouds.reflect.Reflection2.typeTokenOf;
|
||||
import static org.jclouds.reflect.Reflection2.method;
|
||||
import static org.jclouds.reflect.Reflection2.methods;
|
||||
import static org.jclouds.rest.config.BinderUtils.bindHttpApi;
|
||||
import static org.jclouds.util.Maps2.transformKeys;
|
||||
import static org.jclouds.util.Predicates2.startsWith;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
import java.net.URI;
|
||||
import java.util.Arrays;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
|
@ -57,7 +60,7 @@ import com.google.common.cache.CacheBuilder;
|
|||
import com.google.common.collect.ImmutableMap;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import com.google.common.reflect.Invokable;
|
||||
import com.google.common.reflect.TypeToken;
|
||||
import com.google.common.reflect.Parameter;
|
||||
import com.google.inject.AbstractModule;
|
||||
import com.google.inject.Provides;
|
||||
import com.google.inject.TypeLiteral;
|
||||
|
@ -80,7 +83,7 @@ public class RestModule extends AbstractModule {
|
|||
public RestModule(Map<Class<?>, Class<?>> sync2Async) {
|
||||
this.sync2Async = sync2Async;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* seeds well-known invokables.
|
||||
*/
|
||||
|
@ -88,33 +91,42 @@ public class RestModule extends AbstractModule {
|
|||
@Singleton
|
||||
protected Cache<Invokable<?, ?>, Invokable<?, ?>> seedKnownSync2AsyncInvokables() {
|
||||
Cache<Invokable<?, ?>, Invokable<?, ?>> sync2AsyncBuilder = CacheBuilder.newBuilder().build();
|
||||
putInvokables(typeTokenOf(HttpClient.class), typeTokenOf(HttpAsyncClient.class), sync2AsyncBuilder);
|
||||
putInvokables(HttpClient.class, HttpAsyncClient.class, sync2AsyncBuilder);
|
||||
for (Class<?> s : sync2Async.keySet()) {
|
||||
putInvokables(typeTokenOf(s), typeTokenOf(sync2Async.get(s)), sync2AsyncBuilder);
|
||||
putInvokables(s, sync2Async.get(s), sync2AsyncBuilder);
|
||||
}
|
||||
return sync2AsyncBuilder;
|
||||
}
|
||||
|
||||
// accessible for ClientProvider
|
||||
public static void putInvokables(TypeToken<?> sync, TypeToken<?> async, Cache<Invokable<?, ?>, Invokable<?, ?>> cache) {
|
||||
for (Method invoked : sync.getRawType().getMethods()) {
|
||||
public static void putInvokables(Class<?> sync, Class<?> async, Cache<Invokable<?, ?>, Invokable<?, ?>> cache) {
|
||||
for (Invokable<?, ?> invoked : methods(sync)) {
|
||||
if (!objectMethods.contains(invoked)) {
|
||||
try {
|
||||
Method delegatedMethod = async.getRawType().getMethod(invoked.getName(), invoked.getParameterTypes());
|
||||
checkArgument(Arrays.equals(delegatedMethod.getExceptionTypes(), invoked.getExceptionTypes()),
|
||||
Invokable<?, ?> delegatedMethod = method(async, invoked.getName(), getParameterTypes(invoked));
|
||||
checkArgument(delegatedMethod.getExceptionTypes().equals(invoked.getExceptionTypes()),
|
||||
"invoked %s has different typed exceptions than delegated invoked %s", invoked, delegatedMethod);
|
||||
invoked.setAccessible(true);
|
||||
delegatedMethod.setAccessible(true);
|
||||
cache.put(sync.method(invoked), async.method(delegatedMethod));
|
||||
cache.put(invoked, delegatedMethod);
|
||||
} catch (SecurityException e) {
|
||||
throw propagate(e);
|
||||
} catch (NoSuchMethodException e) {
|
||||
throw propagate(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* for portability with {@link Class#getMethod(String, Class...)}
|
||||
*/
|
||||
private static Class<?>[] getParameterTypes(Invokable<?, ?> in) {
|
||||
return toArray(transform(checkNotNull(in, "invokable").getParameters(), new Function<Parameter, Class<?>>() {
|
||||
public Class<?> apply(Parameter input) {
|
||||
return input.getType().getRawType();
|
||||
}
|
||||
}), Class.class);
|
||||
}
|
||||
|
||||
protected void installLocations() {
|
||||
install(new LocationModule());
|
||||
}
|
||||
|
|
|
@ -19,7 +19,7 @@
|
|||
package org.jclouds.rest.internal;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
import static org.jclouds.reflect.Reflection2.typeTokenOf;
|
||||
import static org.jclouds.reflect.Reflection2.typeToken;
|
||||
|
||||
import java.util.Properties;
|
||||
|
||||
|
@ -72,7 +72,7 @@ public abstract class BaseRestApiMetadata extends BaseApiMetadata implements Res
|
|||
checkNotNull(asyncApi, "asyncApi");
|
||||
javaApi(api, asyncApi)
|
||||
.name(String.format("%s->%s", api.getSimpleName(), asyncApi.getSimpleName()))
|
||||
.context(contextToken(typeTokenOf(api), typeTokenOf(asyncApi)))
|
||||
.context(contextToken(typeToken(api), typeToken(asyncApi)))
|
||||
.defaultProperties(BaseRestApiMetadata.defaultProperties());
|
||||
}
|
||||
|
||||
|
|
|
@ -23,7 +23,8 @@ import static com.google.common.base.Throwables.propagate;
|
|||
import static com.google.common.collect.Iterables.all;
|
||||
import static com.google.common.collect.Iterables.find;
|
||||
import static com.google.inject.util.Types.newParameterizedType;
|
||||
import static org.jclouds.reflect.Reflection2.typeTokenOf;
|
||||
import static org.jclouds.reflect.Reflection2.method;
|
||||
import static org.jclouds.reflect.Reflection2.typeToken;
|
||||
import static org.jclouds.util.Optionals2.isReturnTypeOptional;
|
||||
import static org.jclouds.util.Optionals2.unwrapIfOptional;
|
||||
import static org.jclouds.util.Throwables2.getFirstThrowableOfType;
|
||||
|
@ -66,7 +67,6 @@ import com.google.inject.Injector;
|
|||
import com.google.inject.Key;
|
||||
import com.google.inject.Provides;
|
||||
import com.google.inject.ProvisionException;
|
||||
import com.google.inject.TypeLiteral;
|
||||
import com.google.inject.util.Types;
|
||||
|
||||
/**
|
||||
|
@ -96,10 +96,11 @@ public final class DelegatesToInvocationFunction<S, F extends Function<Invocatio
|
|||
* </ul>
|
||||
* <li>other method calls are dispatched to {@link #handleInvocation}.
|
||||
* </ul>
|
||||
* @throws Throwable
|
||||
*
|
||||
* @throws Throwable
|
||||
*/
|
||||
@Override
|
||||
public final Object invoke(Object proxy, Method invoked, @Nullable Object[] argv) throws Throwable {
|
||||
public final Object invoke(Object proxy, Method invoked, @Nullable Object[] argv) throws Throwable {
|
||||
if (argv == null) {
|
||||
argv = NO_ARGS;
|
||||
}
|
||||
|
@ -118,7 +119,7 @@ public final class DelegatesToInvocationFunction<S, F extends Function<Invocatio
|
|||
args = ImmutableList.copyOf(args);
|
||||
else
|
||||
args = Collections.unmodifiableList(args);
|
||||
Invokable<?, Object> invokable = enclosingType.method(invoked);
|
||||
Invokable<?, Object> invokable = method(ownerType, invoked);
|
||||
Invocation invocation = Invocation.create(invokable, args);
|
||||
try {
|
||||
return handle(invocation);
|
||||
|
@ -135,20 +136,19 @@ public final class DelegatesToInvocationFunction<S, F extends Function<Invocatio
|
|||
return propagateContextToDelegate(invocation);
|
||||
return methodInvoker.apply(invocation);
|
||||
}
|
||||
|
||||
|
||||
private final Injector injector;
|
||||
private final TypeToken<S> enclosingType;
|
||||
private final TypeToken<S> ownerType;
|
||||
private final SetCaller setCaller;
|
||||
private final Map<Class<?>, Class<?>> syncToAsync;
|
||||
private final Function<InvocationSuccess, Optional<Object>> optionalConverter;
|
||||
private final F methodInvoker;
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Inject
|
||||
DelegatesToInvocationFunction(Injector injector, SetCaller setCaller, Map<Class<?>, Class<?>> syncToAsync,
|
||||
TypeLiteral<S> enclosingType, Function<InvocationSuccess, Optional<Object>> optionalConverter, F methodInvoker) {
|
||||
Class<S> ownerType, Function<InvocationSuccess, Optional<Object>> optionalConverter, F methodInvoker) {
|
||||
this.injector = checkNotNull(injector, "injector");
|
||||
this.enclosingType = (TypeToken<S>) typeTokenOf(checkNotNull(enclosingType, "enclosingType").getType());
|
||||
this.ownerType = typeToken(checkNotNull(ownerType, "ownerType"));
|
||||
this.setCaller = checkNotNull(setCaller, "setCaller");
|
||||
this.syncToAsync = checkNotNull(syncToAsync, "syncToAsync");
|
||||
this.optionalConverter = checkNotNull(optionalConverter, "optionalConverter");
|
||||
|
@ -174,7 +174,7 @@ public final class DelegatesToInvocationFunction<S, F extends Function<Invocatio
|
|||
}
|
||||
|
||||
/**
|
||||
* attempts to guess the generic type params for the delegate's invocation function based on the supplied type
|
||||
* attempts to guess the generic type params for the delegate's invocation function based on the supplied type
|
||||
*/
|
||||
private Key<?> methodInvokerFor(Class<?> returnType) {
|
||||
switch (methodInvoker.getClass().getTypeParameters().length) {
|
||||
|
@ -256,8 +256,7 @@ public final class DelegatesToInvocationFunction<S, F extends Function<Invocatio
|
|||
|
||||
@Override
|
||||
public String toString() {
|
||||
return Objects.toStringHelper("").omitNullValues()
|
||||
.add("enclosingType", enclosingType.getRawType().getSimpleName()).add("methodInvoker", methodInvoker)
|
||||
.toString();
|
||||
return Objects.toStringHelper("").omitNullValues().add("ownerType", ownerType.getRawType().getSimpleName())
|
||||
.add("methodInvoker", methodInvoker).toString();
|
||||
}
|
||||
}
|
|
@ -18,7 +18,7 @@
|
|||
*/
|
||||
package org.jclouds.apis;
|
||||
|
||||
import static org.jclouds.reflect.Reflection2.typeTokenOf;
|
||||
import static org.jclouds.reflect.Reflection2.typeToken;
|
||||
|
||||
import java.util.Properties;
|
||||
|
||||
|
@ -48,7 +48,7 @@ public abstract class BaseViewLiveTest<V extends View> extends BaseContextLiveTe
|
|||
|
||||
@Override
|
||||
protected TypeToken<Context> contextType() {
|
||||
return typeTokenOf(Context.class);
|
||||
return typeToken(Context.class);
|
||||
}
|
||||
|
||||
protected V createView(Properties props, Iterable<Module> modules) {
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
package org.jclouds.http.functions;
|
||||
|
||||
import static com.google.common.base.Throwables.propagate;
|
||||
import static org.jclouds.reflect.Reflection2.method;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
|
@ -29,7 +30,6 @@ import org.testng.annotations.AfterTest;
|
|||
import org.testng.annotations.BeforeTest;
|
||||
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.google.common.reflect.Invokable;
|
||||
import com.google.inject.Guice;
|
||||
import com.google.inject.Injector;
|
||||
|
||||
|
@ -54,11 +54,9 @@ public class BaseHandlerTest {
|
|||
@BeforeTest
|
||||
protected void setUpRequest() {
|
||||
try {
|
||||
toString = Invocation.create(Invokable.from(String.class.getDeclaredMethod("toString")), ImmutableList.of());
|
||||
toString = Invocation.create(method(String.class, "toString"), ImmutableList.of());
|
||||
} catch (SecurityException e) {
|
||||
throw propagate(e);
|
||||
} catch (NoSuchMethodException e) {
|
||||
throw propagate(e);
|
||||
}
|
||||
request = GeneratedHttpRequest.builder().method("POST").endpoint("http://localhost/key").invocation(toString)
|
||||
.build();
|
||||
|
|
|
@ -17,7 +17,7 @@
|
|||
* under the License.
|
||||
*/
|
||||
package org.jclouds.http.handlers;
|
||||
|
||||
import static org.jclouds.reflect.Reflection2.method;
|
||||
import static org.testng.Assert.assertEquals;
|
||||
import static org.testng.Assert.assertTrue;
|
||||
|
||||
|
@ -125,7 +125,7 @@ public class BackoffLimitedRetryHandlerTest {
|
|||
.getInstance(RestAnnotationProcessor.class);
|
||||
|
||||
private HttpCommand createCommand() throws SecurityException, NoSuchMethodException {
|
||||
Invokable<?, Object> method = Invokable.from(IntegrationTestAsyncClient.class.getMethod("download", String.class));
|
||||
Invokable<IntegrationTestAsyncClient, String> method = method(IntegrationTestAsyncClient.class, "download", String.class);
|
||||
|
||||
return new HttpCommand(processor.createRequest(method, ImmutableList.<Object> of("1")));
|
||||
}
|
||||
|
|
|
@ -19,7 +19,7 @@
|
|||
package org.jclouds.internal;
|
||||
|
||||
import static org.easymock.EasyMock.createMock;
|
||||
import static org.jclouds.reflect.Reflection2.typeTokenOf;
|
||||
import static org.jclouds.reflect.Reflection2.typeToken;
|
||||
import static org.testng.Assert.assertEquals;
|
||||
import static org.testng.Assert.assertNotEquals;
|
||||
import static org.testng.Assert.fail;
|
||||
|
@ -64,22 +64,22 @@ public class BaseViewTest {
|
|||
private static class Wine extends BaseView {
|
||||
|
||||
protected Wine() {
|
||||
super(new Water(), typeTokenOf(Water.class));
|
||||
super(new Water(), typeToken(Water.class));
|
||||
}
|
||||
}
|
||||
|
||||
public void testWaterTurnedIntoWine() {
|
||||
Wine wine = new Wine();
|
||||
assertEquals(wine.getBackendType(), typeTokenOf(Water.class));
|
||||
assertEquals(wine.unwrap(typeTokenOf(Water.class)).getClass(), Water.class);
|
||||
assertEquals(wine.getBackendType(), typeToken(Water.class));
|
||||
assertEquals(wine.unwrap(typeToken(Water.class)).getClass(), Water.class);
|
||||
assertEquals(wine.unwrap().getClass(), Water.class);
|
||||
}
|
||||
|
||||
public void testPeanutButterDidntTurnIntoWine() {
|
||||
Wine wine = new Wine();
|
||||
assertNotEquals(wine.getBackendType(), typeTokenOf(PeanutButter.class));
|
||||
assertNotEquals(wine.getBackendType(), typeToken(PeanutButter.class));
|
||||
try {
|
||||
wine.unwrap(typeTokenOf(PeanutButter.class));
|
||||
wine.unwrap(typeToken(PeanutButter.class));
|
||||
fail();
|
||||
} catch (IllegalArgumentException e) {
|
||||
assertEquals(e.getMessage(), "backend type: org.jclouds.internal.BaseViewTest$Water not assignable from org.jclouds.internal.BaseViewTest$PeanutButter");
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
*/
|
||||
package org.jclouds.json;
|
||||
|
||||
import static org.jclouds.reflect.Reflection2.method;
|
||||
import static org.testng.Assert.assertEquals;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
|
@ -39,7 +40,6 @@ import org.testng.annotations.Test;
|
|||
import com.google.common.base.Function;
|
||||
import com.google.common.base.Throwables;
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.google.common.reflect.Invokable;
|
||||
import com.google.inject.Guice;
|
||||
import com.google.inject.Injector;
|
||||
|
||||
|
@ -62,8 +62,7 @@ public abstract class BaseParserTest<T, G> {
|
|||
return (Function<HttpResponse, T>) i
|
||||
.createChildInjector(new SaxParserModule())
|
||||
.getInstance(TransformerForRequest.class)
|
||||
.getTransformerForMethod(
|
||||
Invocation.create(Invokable.from(getClass().getMethod("expected")), ImmutableList.of()), i);
|
||||
.getTransformerForMethod(Invocation.create(method(getClass(), "expected"), ImmutableList.of()), i);
|
||||
} catch (Exception e) {
|
||||
throw Throwables.propagate(e);
|
||||
}
|
||||
|
|
|
@ -19,7 +19,7 @@
|
|||
package org.jclouds.providers.internal;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
import static org.jclouds.reflect.Reflection2.typeTokenOf;
|
||||
import static org.jclouds.reflect.Reflection2.typeToken;
|
||||
import static org.testng.Assert.assertEquals;
|
||||
|
||||
import java.util.Set;
|
||||
|
@ -63,7 +63,7 @@ public abstract class BaseProviderMetadataTest {
|
|||
public void testOfApiContains() {
|
||||
if (expectedApi == null)
|
||||
Logger.getAnonymousLogger().warning("please update your test class");
|
||||
ImmutableSet<ProviderMetadata> ofApi = ImmutableSet.copyOf(Providers.apiMetadataAssignableFrom(typeTokenOf(expectedApi.getClass())));
|
||||
ImmutableSet<ProviderMetadata> ofApi = ImmutableSet.copyOf(Providers.apiMetadataAssignableFrom(typeToken(expectedApi.getClass())));
|
||||
assert ofApi.contains(toTest) : String.format("%s not found in %s", toTest, ofApi);
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,79 @@
|
|||
/**
|
||||
* Licensed to jclouds, Inc. (jclouds) under one or more
|
||||
* contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. jclouds licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
package org.jclouds.reflect;
|
||||
|
||||
import static com.google.common.base.Functions.toStringFunction;
|
||||
import static org.jclouds.reflect.Reflection2.method;
|
||||
import static org.jclouds.reflect.Reflection2.methods;
|
||||
import static org.jclouds.reflect.Reflection2.typeToken;
|
||||
import static org.testng.Assert.assertEquals;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
import com.google.common.base.Function;
|
||||
import com.google.common.collect.FluentIterable;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import com.google.common.reflect.Invokable;
|
||||
import com.google.common.reflect.TypeToken;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
@Test
|
||||
public class Reflection2Test {
|
||||
|
||||
public void testTypeToken() {
|
||||
assertEquals(typeToken(String.class), TypeToken.of(String.class));
|
||||
}
|
||||
|
||||
public void testMethodFromJavaMethod() throws SecurityException, NoSuchMethodException {
|
||||
assertEquals(method(typeToken(String.class), String.class.getMethod("toString")), TypeToken.of(String.class)
|
||||
.method(String.class.getMethod("toString")).returning(String.class));
|
||||
}
|
||||
|
||||
public void testMethodFromClassAndNoParams() {
|
||||
@SuppressWarnings("rawtypes")
|
||||
Invokable<Set, Object> methodInSuper = method(Set.class, "iterator");
|
||||
|
||||
assertEquals(methodInSuper.getOwnerType(), typeToken(Set.class));
|
||||
}
|
||||
|
||||
public void testMethodFromClassAndParams() {
|
||||
@SuppressWarnings("rawtypes")
|
||||
Invokable<Set, Object> methodInSuper = method(Set.class, "equals", Object.class);
|
||||
|
||||
assertEquals(methodInSuper.getOwnerType(), typeToken(Set.class));
|
||||
assertEquals(methodInSuper.getParameters().get(0).getType().getRawType(), Object.class);
|
||||
}
|
||||
|
||||
public void testMethods() {
|
||||
Set<String> methodNames = FluentIterable.from(methods(Set.class))
|
||||
.transform(new Function<Invokable<?, ?>, String>() {
|
||||
public String apply(Invokable<?, ?> input) {
|
||||
return input.getName();
|
||||
}
|
||||
}).transform(toStringFunction()).toSet();
|
||||
|
||||
assertEquals(methodNames, ImmutableSet.of("add", "equals", "hashCode", "clear", "isEmpty", "contains", "addAll",
|
||||
"size", "toArray", "iterator", "remove", "removeAll", "containsAll", "retainAll"));
|
||||
}
|
||||
}
|
|
@ -18,6 +18,8 @@
|
|||
*/
|
||||
package org.jclouds.rest;
|
||||
|
||||
import static org.jclouds.reflect.Reflection2.method;
|
||||
|
||||
import javax.ws.rs.POST;
|
||||
import javax.ws.rs.PathParam;
|
||||
|
||||
|
@ -36,7 +38,6 @@ import org.testng.annotations.Test;
|
|||
import com.google.common.collect.ImmutableList;
|
||||
import com.google.common.reflect.Invokable;
|
||||
import com.google.inject.Injector;
|
||||
|
||||
@Test(groups = "unit")
|
||||
public class InputParamValidatorTest {
|
||||
|
||||
|
@ -59,10 +60,10 @@ public class InputParamValidatorTest {
|
|||
*/
|
||||
@Test
|
||||
public void testInputParamsValidation() throws Exception {
|
||||
Invokable<?, ?> allParamsValidatedMethod = Invokable.from(InputParamValidatorForm.class.getMethod(
|
||||
"allParamsValidated", String.class, String.class));
|
||||
Invokable<?, ?> oneParamValidatedMethod = Invokable.from(InputParamValidatorForm.class.getMethod(
|
||||
"oneParamValidated", String.class, String.class));
|
||||
Invokable<?, ?> allParamsValidatedMethod = method(InputParamValidatorForm.class, "allParamsValidated",
|
||||
String.class, String.class);
|
||||
Invokable<?, ?> oneParamValidatedMethod = method(InputParamValidatorForm.class, "oneParamValidated",
|
||||
String.class, String.class);
|
||||
restAnnotationProcessor.createRequest(allParamsValidatedMethod, ImmutableList.<Object> of("blah", "blah"));
|
||||
restAnnotationProcessor.createRequest(oneParamValidatedMethod, ImmutableList.<Object> of("blah", "blah"));
|
||||
|
||||
|
@ -98,7 +99,7 @@ public class InputParamValidatorTest {
|
|||
|
||||
@Test(expectedExceptions = ClassCastException.class)
|
||||
public void testWrongPredicateTypeLiteral() throws Exception {
|
||||
Invocation invocation = Invocation.create(Invokable.from(WrongValidator.class.getMethod("method", Integer.class)),
|
||||
Invocation invocation = Invocation.create(method(WrongValidator.class, "method", Integer.class),
|
||||
ImmutableList.<Object> of(55));
|
||||
new InputParamValidator(injector).validateMethodParametersOrThrow(invocation);
|
||||
}
|
||||
|
|
|
@ -0,0 +1,148 @@
|
|||
/**
|
||||
* Licensed to jclouds, Inc. (jclouds) under one or more
|
||||
* contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. jclouds licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
package org.jclouds.rest.annotationparsing;
|
||||
|
||||
import static org.jclouds.providers.AnonymousProviderMetadata.forClientMappedToAsyncClientOnEndpoint;
|
||||
import static org.testng.Assert.assertEquals;
|
||||
|
||||
import java.util.NoSuchElementException;
|
||||
import java.util.Set;
|
||||
|
||||
import javax.inject.Named;
|
||||
|
||||
import org.jclouds.http.HttpRequest;
|
||||
import org.jclouds.http.HttpResponse;
|
||||
import org.jclouds.providers.ProviderMetadata;
|
||||
import org.jclouds.rest.AuthorizationException;
|
||||
import org.jclouds.rest.ConfiguresRestClient;
|
||||
import org.jclouds.rest.config.RestClientModule;
|
||||
import org.jclouds.rest.internal.BaseRestClientExpectTest;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import com.google.inject.Module;
|
||||
import com.google.inject.Provides;
|
||||
import com.google.inject.TypeLiteral;
|
||||
import com.google.inject.name.Names;
|
||||
|
||||
/**
|
||||
* Tests that we can add {@link Provides} methods on interfaces
|
||||
*
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
@Test(groups = "unit", testName = "ProvidesAnnotationExpectTest")
|
||||
public class ProvidesAnnotationExpectTest extends BaseRestClientExpectTest<ProvidesAnnotationExpectTest.ProvidingApi> {
|
||||
|
||||
static interface ProvidingApi {
|
||||
@Provides
|
||||
Set<String> set();
|
||||
|
||||
@Named("bar")
|
||||
@Provides
|
||||
Set<String> foo();
|
||||
|
||||
@Named("exception")
|
||||
@Provides
|
||||
Set<String> exception();
|
||||
|
||||
@Named("NoSuchElementException")
|
||||
@Provides
|
||||
Set<String> noSuchElementException();
|
||||
}
|
||||
|
||||
static interface ProvidingAsyncApi {
|
||||
@Provides
|
||||
Set<String> set();
|
||||
|
||||
@Named("bar")
|
||||
@Provides
|
||||
Set<String> foo();
|
||||
|
||||
@Named("exception")
|
||||
@Provides
|
||||
Set<String> exception();
|
||||
|
||||
@Named("NoSuchElementException")
|
||||
@Provides
|
||||
Set<String> noSuchElementException();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testProvidesWithGeneric(){
|
||||
ProvidingApi client = requestsSendResponses(ImmutableMap.<HttpRequest, HttpResponse> of());
|
||||
assertEquals(client.set(), ImmutableSet.of("foo"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testProvidesWithGenericQualified(){
|
||||
ProvidingApi client = requestsSendResponses(ImmutableMap.<HttpRequest, HttpResponse> of());
|
||||
assertEquals(client.foo(), ImmutableSet.of("bar"));
|
||||
}
|
||||
|
||||
@Test(expectedExceptions = AuthorizationException.class)
|
||||
public void testProvidesWithGenericQualifiedAuthorizationException(){
|
||||
ProvidingApi client = requestsSendResponses(ImmutableMap.<HttpRequest, HttpResponse> of());
|
||||
client.exception();
|
||||
}
|
||||
|
||||
@Test(expectedExceptions = NoSuchElementException.class)
|
||||
public void testProvidesWithGenericQualifiedNoSuchElementException(){
|
||||
ProvidingApi client = requestsSendResponses(ImmutableMap.<HttpRequest, HttpResponse> of());
|
||||
client.noSuchElementException();
|
||||
}
|
||||
|
||||
// crufty junk until we inspect delegating api classes for all their client
|
||||
// mappings and make a test helper for random classes.
|
||||
|
||||
@Override
|
||||
public ProviderMetadata createProviderMetadata() {
|
||||
return forClientMappedToAsyncClientOnEndpoint(ProvidingApi.class, ProvidingAsyncApi.class, "http://mock");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Module createModule() {
|
||||
return new ProvidingRestClientModule();
|
||||
}
|
||||
|
||||
@ConfiguresRestClient
|
||||
static class ProvidingRestClientModule extends RestClientModule<ProvidingApi, ProvidingAsyncApi> {
|
||||
|
||||
@Override
|
||||
protected void configure() {
|
||||
super.configure();
|
||||
bind(new TypeLiteral<Set<String>>() {
|
||||
}).toInstance(ImmutableSet.of("foo"));
|
||||
bind(new TypeLiteral<Set<String>>() {
|
||||
}).annotatedWith(Names.named("bar")).toInstance(ImmutableSet.of("bar"));
|
||||
}
|
||||
|
||||
@Provides
|
||||
@Named("exception")
|
||||
Set<String> exception() {
|
||||
throw new AuthorizationException();
|
||||
}
|
||||
|
||||
@Provides
|
||||
@Named("NoSuchElementException")
|
||||
Set<String> noSuchElementException() {
|
||||
throw new NoSuchElementException();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -18,6 +18,7 @@
|
|||
*/
|
||||
package org.jclouds.rest.binders;
|
||||
|
||||
import static org.jclouds.reflect.Reflection2.method;
|
||||
import static org.testng.Assert.assertEquals;
|
||||
|
||||
import java.io.File;
|
||||
|
@ -33,10 +34,7 @@ import org.testng.annotations.Test;
|
|||
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import com.google.common.reflect.TypeToken;
|
||||
|
||||
import com.google.common.reflect.Invokable;
|
||||
|
||||
/**
|
||||
* Tests behavior of {@code BindMapToStringPayload}
|
||||
*
|
||||
|
@ -56,7 +54,7 @@ public class BindMapToStringPayloadTest {
|
|||
|
||||
@Test
|
||||
public void testCorrect() throws SecurityException, NoSuchMethodException {
|
||||
Invokable<?, Object> testPayload = Invokable.from(TestPayload.class.getMethod("testPayload", String.class));
|
||||
Invokable<?, Object> testPayload = method(TestPayload.class, "testPayload", String.class);
|
||||
GeneratedHttpRequest request = GeneratedHttpRequest.builder()
|
||||
.invocation(Invocation.create(testPayload, ImmutableList.<Object> of("robot")))
|
||||
.method("POST").endpoint("http://localhost").build();
|
||||
|
@ -70,7 +68,7 @@ public class BindMapToStringPayloadTest {
|
|||
|
||||
@Test
|
||||
public void testDecodes() throws SecurityException, NoSuchMethodException {
|
||||
Invokable<?, Object> testPayload = Invokable.from(TestPayload.class.getMethod("changeAdminPass", String.class));
|
||||
Invokable<?, Object> testPayload = method(TestPayload.class, "changeAdminPass", String.class);
|
||||
GeneratedHttpRequest request = GeneratedHttpRequest.builder()
|
||||
.invocation(Invocation.create(testPayload, ImmutableList.<Object> of("foo")))
|
||||
.method("POST").endpoint("http://localhost").build();
|
||||
|
@ -84,7 +82,7 @@ public class BindMapToStringPayloadTest {
|
|||
|
||||
@Test(expectedExceptions = IllegalArgumentException.class)
|
||||
public void testMustHavePayloadAnnotation() throws SecurityException, NoSuchMethodException {
|
||||
Invokable<?, Object> noPayload = Invokable.from(TestPayload.class.getMethod("noPayload", String.class));
|
||||
Invokable<?, Object> noPayload = method(TestPayload.class, "noPayload", String.class);
|
||||
GeneratedHttpRequest request = GeneratedHttpRequest.builder()
|
||||
.invocation(Invocation.create(noPayload, ImmutableList.<Object> of("robot")))
|
||||
.method("POST").endpoint("http://localhost").build();
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
package org.jclouds.rest.functions;
|
||||
|
||||
import static com.google.common.base.Throwables.propagate;
|
||||
import static org.jclouds.reflect.Reflection2.method;
|
||||
import static org.testng.Assert.assertEquals;
|
||||
import static org.testng.Assert.assertTrue;
|
||||
|
||||
|
@ -35,7 +36,6 @@ import org.testng.annotations.Test;
|
|||
import com.google.common.base.Optional;
|
||||
import com.google.common.base.Stopwatch;
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.google.common.reflect.Invokable;
|
||||
|
||||
/**
|
||||
* Allows you to use simple api version comparison to determine if a feature is
|
||||
|
@ -165,9 +165,9 @@ public class PresentWhenApiVersionLexicographicallyAtOrAfterSinceApiVersionTest
|
|||
|
||||
InvocationSuccess getApi(String name, Class<?> target) {
|
||||
try {
|
||||
return InvocationSuccess.create(Invocation.create(
|
||||
Invokable.from(EC2AsyncApi.class.getDeclaredMethod("get" + name + "ApiForRegion", String.class)),
|
||||
ImmutableList.<Object> of("region")), "present");
|
||||
return InvocationSuccess.create(
|
||||
Invocation.create(method(EC2AsyncApi.class, "get" + name + "ApiForRegion", String.class),
|
||||
ImmutableList.<Object> of("region")), "present");
|
||||
} catch (Exception e) {
|
||||
throw propagate(e);
|
||||
}
|
||||
|
|
|
@ -17,8 +17,7 @@
|
|||
* under the License.
|
||||
*/
|
||||
package org.jclouds.rest.internal;
|
||||
|
||||
import static org.jclouds.reflect.Reflection2.typeTokenOf;
|
||||
import static org.jclouds.reflect.Reflection2.typeToken;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
|
@ -46,7 +45,7 @@ public abstract class BaseRestApiMetadataTest extends BaseApiMetadataTest {
|
|||
|
||||
@Test
|
||||
public void testContextAssignableFromRestContext() {
|
||||
Set<ApiMetadata> all = ImmutableSet.copyOf(Apis.contextAssignableFrom(typeTokenOf(RestContext.class)));
|
||||
Set<ApiMetadata> all = ImmutableSet.copyOf(Apis.contextAssignableFrom(typeToken(RestContext.class)));
|
||||
assert all.contains(toTest) : String.format("%s not found in %s", toTest, all);
|
||||
}
|
||||
|
||||
|
|
|
@ -22,7 +22,7 @@ import static org.easymock.EasyMock.createMock;
|
|||
import static org.easymock.EasyMock.expect;
|
||||
import static org.easymock.EasyMock.replay;
|
||||
import static org.easymock.EasyMock.verify;
|
||||
import static org.jclouds.reflect.Reflection2.typeTokenOf;
|
||||
import static org.jclouds.reflect.Reflection2.method;
|
||||
import static org.testng.Assert.assertEquals;
|
||||
|
||||
import java.util.concurrent.ExecutionException;
|
||||
|
@ -39,7 +39,6 @@ import org.testng.annotations.Test;
|
|||
import com.google.common.base.Function;
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import com.google.common.reflect.TypeToken;
|
||||
import com.google.common.util.concurrent.ListenableFuture;
|
||||
|
||||
/**
|
||||
|
@ -62,16 +61,13 @@ public class BlockOnFutureTest {
|
|||
}
|
||||
}
|
||||
|
||||
private TypeToken<ThingAsyncApi> enclosingType;
|
||||
private Invocation get;
|
||||
private Invocation namedGet;
|
||||
|
||||
@BeforeClass
|
||||
void setupInvocations() throws SecurityException, NoSuchMethodException {
|
||||
enclosingType = typeTokenOf(ThingAsyncApi.class);
|
||||
get = Invocation.create(enclosingType.method(ThingAsyncApi.class.getDeclaredMethod("get")), ImmutableList.of());
|
||||
namedGet = Invocation.create(enclosingType.method(ThingAsyncApi.class.getDeclaredMethod("namedGet")),
|
||||
ImmutableList.of());
|
||||
get = Invocation.create(method(ThingAsyncApi.class, "get"), ImmutableList.of());
|
||||
namedGet = Invocation.create(method(ThingAsyncApi.class, "namedGet"), ImmutableList.of());
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -17,7 +17,7 @@
|
|||
* under the License.
|
||||
*/
|
||||
package org.jclouds.util;
|
||||
|
||||
import static org.jclouds.reflect.Reflection2.method;
|
||||
import static org.testng.Assert.assertEquals;
|
||||
import static org.testng.Assert.assertFalse;
|
||||
import static org.testng.Assert.assertTrue;
|
||||
|
@ -40,25 +40,25 @@ public class Optionals2Test {
|
|||
}
|
||||
|
||||
public void testReturnTypeOrTypeOfOptionalWhenOptional() throws SecurityException, NoSuchMethodException {
|
||||
Invokable<?, ?> invoked = Invokable.from(Test.class.getMethod("getOptional"));
|
||||
Invokable<?, ?> invoked = method(Test.class, "getOptional");
|
||||
|
||||
assertEquals(Optionals2.unwrapIfOptional(invoked.getReturnType()), String.class);
|
||||
}
|
||||
|
||||
public void testReturnTypeOrTypeOfOptionalWhenNotOptional() throws SecurityException, NoSuchMethodException {
|
||||
Invokable<?, ?> invoked = Invokable.from(Test.class.getMethod("getNotOptional"));
|
||||
Invokable<?, ?> invoked = method(Test.class, "getNotOptional");
|
||||
|
||||
assertEquals(Optionals2.unwrapIfOptional(invoked.getReturnType()), String.class);
|
||||
}
|
||||
|
||||
public void testIsReturnTypeOptionalWhenOptional() throws SecurityException, NoSuchMethodException {
|
||||
Invokable<?, ?> invoked = Invokable.from(Test.class.getMethod("getOptional"));
|
||||
Invokable<?, ?> invoked = method(Test.class, "getOptional");
|
||||
|
||||
assertTrue(Optionals2.isReturnTypeOptional(invoked));
|
||||
}
|
||||
|
||||
public void testIsReturnTypeOptionalWhenNotOptional() throws SecurityException, NoSuchMethodException {
|
||||
Invokable<?, ?> invoked = Invokable.from(Test.class.getMethod("getNotOptional"));
|
||||
Invokable<?, ?> invoked = method(Test.class, "getNotOptional");
|
||||
|
||||
assertFalse(Optionals2.isReturnTypeOptional(invoked));
|
||||
}
|
||||
|
|
|
@ -20,7 +20,7 @@ package org.jclouds.util;
|
|||
|
||||
import static org.easymock.EasyMock.createMock;
|
||||
import static org.easymock.EasyMock.createNiceMock;
|
||||
import static org.jclouds.reflect.Reflection2.typeTokenOf;
|
||||
import static org.jclouds.reflect.Reflection2.typeToken;
|
||||
import static org.jclouds.util.Throwables2.getFirstThrowableOfType;
|
||||
import static org.jclouds.util.Throwables2.propagateIfPossible;
|
||||
import static org.testng.Assert.assertEquals;
|
||||
|
@ -148,14 +148,14 @@ public class Throwables2Test {
|
|||
@Test(expectedExceptions = TestException.class)
|
||||
public void testPropagateExceptionThatsInList() throws Throwable {
|
||||
Exception e = new TestException();
|
||||
propagateIfPossible(e, ImmutableSet.<TypeToken<? extends Throwable>> of(typeTokenOf(TestException.class)));
|
||||
propagateIfPossible(e, ImmutableSet.<TypeToken<? extends Throwable>> of(typeToken(TestException.class)));
|
||||
}
|
||||
|
||||
@Test(expectedExceptions = TestException.class)
|
||||
public void testPropagateWrappedExceptionThatsInList() throws Throwable {
|
||||
Exception e = new TestException();
|
||||
propagateIfPossible(new RuntimeException(e),
|
||||
ImmutableSet.<TypeToken<? extends Throwable>> of(typeTokenOf(TestException.class)));
|
||||
ImmutableSet.<TypeToken<? extends Throwable>> of(typeToken(TestException.class)));
|
||||
}
|
||||
|
||||
public void testPropagateIfPossibleDoesnThrowExceptionNotInList() throws Throwable {
|
||||
|
|
Loading…
Reference in New Issue