migrated from j.l.r.Method -> Invokable

This commit is contained in:
Adrian Cole 2013-01-05 18:51:03 -08:00
parent c43aac2ecc
commit 69c7cd74df
19 changed files with 461 additions and 618 deletions

View File

@ -24,6 +24,7 @@ import static com.google.common.base.Preconditions.checkState;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ExecutionException;
@ -36,6 +37,7 @@ import javax.inject.Named;
import org.jclouds.internal.ClassInvokerArgs;
import org.jclouds.internal.ClassInvokerArgsAndReturnVal;
import org.jclouds.logging.Logger;
import org.jclouds.reflect.AbstractInvocationHandler;
import org.jclouds.rest.annotations.Delegate;
import org.jclouds.util.Optionals2;
import org.jclouds.util.Throwables2;
@ -47,7 +49,7 @@ import com.google.common.base.Throwables;
import com.google.common.cache.LoadingCache;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
import com.google.common.reflect.AbstractInvocationHandler;
import com.google.common.reflect.Invokable;
import com.google.common.util.concurrent.ListenableFuture;
import com.google.inject.ProvisionException;
import com.google.inject.assistedinject.Assisted;
@ -77,13 +79,14 @@ public final class SyncProxy extends AbstractInvocationHandler {
private final Function<ClassInvokerArgsAndReturnVal, Optional<Object>> optionalConverter;
private final Object delegate;
private final Class<?> declaring;
private final Map<Method, Method> methodMap;
private final Map<Method, Method> syncMethodMap;
private final Map<Method, Optional<Long>> timeoutMap;
private final Map<Invokable<?, ?>, Invokable<Object, ListenableFuture<?>>> methodMap;
private final Map<Invokable<?, ?>, Invokable<Object, ?>> syncMethodMap;
private final Map<Invokable<?, ?>, Optional<Long>> timeoutMap;
private final LoadingCache<ClassInvokerArgs, Object> delegateMap;
private final Map<Class<?>, Class<?>> sync2Async;
private static final Set<Method> objectMethods = ImmutableSet.copyOf(Object.class.getMethods());
@SuppressWarnings("unchecked")
@Inject
@VisibleForTesting
SyncProxy(Function<ClassInvokerArgsAndReturnVal, Optional<Object>> optionalConverter,
@ -96,8 +99,8 @@ public final class SyncProxy extends AbstractInvocationHandler {
this.declaring = declaring;
this.sync2Async = ImmutableMap.copyOf(sync2Async);
ImmutableMap.Builder<Method, Method> methodMapBuilder = ImmutableMap.builder();
ImmutableMap.Builder<Method, Method> syncMethodMapBuilder = ImmutableMap.builder();
ImmutableMap.Builder<Invokable<?, ?>, Invokable<Object, ListenableFuture<?>>> methodMapBuilder = ImmutableMap.builder();
ImmutableMap.Builder<Invokable<?, ?>, Invokable<Object, ?>> syncMethodMapBuilder = ImmutableMap.builder();
for (Method method : declaring.getMethods()) {
if (!objectMethods.contains(method)) {
@ -106,17 +109,17 @@ public final class SyncProxy extends AbstractInvocationHandler {
throw new IllegalArgumentException(String.format(
"method %s has different typed exceptions than delegated method %s", method, delegatedMethod));
if (delegatedMethod.getReturnType().isAssignableFrom(ListenableFuture.class)) {
methodMapBuilder.put(method, delegatedMethod);
methodMapBuilder.put(Invokable.from(method), Invokable.class.cast(Invokable.from(delegatedMethod)));
} else {
syncMethodMapBuilder.put(method, delegatedMethod);
syncMethodMapBuilder.put(Invokable.from(method), Invokable.class.cast(Invokable.from(delegatedMethod)));
}
}
}
methodMap = methodMapBuilder.build();
syncMethodMap = syncMethodMapBuilder.build();
ImmutableMap.Builder<Method, Optional<Long>> timeoutMapBuilder = ImmutableMap.builder();
for (Method method : methodMap.keySet()) {
ImmutableMap.Builder<Invokable<?, ?>, Optional<Long>> timeoutMapBuilder = ImmutableMap.builder();
for (Invokable<?, ?> method : methodMap.keySet()) {
timeoutMapBuilder.put(method, timeoutInNanos(method, timeouts));
}
timeoutMap = timeoutMapBuilder.build();
@ -127,7 +130,7 @@ public final class SyncProxy extends AbstractInvocationHandler {
}
@Override
protected Object handleInvocation(Object o, Method method, Object[] args) throws Exception {
protected Object handleInvocation(Object proxy, Invokable<?, ?> method, List<Object> args) throws Throwable {
if (method.isAnnotationPresent(Delegate.class)) {
Class<?> syncClass = Optionals2.returnTypeOrTypeOfOptional(method);
// get the return type of the asynchronous class associated with this client
@ -148,16 +151,16 @@ public final class SyncProxy extends AbstractInvocationHandler {
return returnVal;
} else if (syncMethodMap.containsKey(method)) {
try {
return syncMethodMap.get(method).invoke(delegate, args);
return syncMethodMap.get(method).invoke(delegate, args.toArray());
} catch (InvocationTargetException e) {
throw Throwables.propagate(e.getCause());
}
} else {
try {
Optional<Long> timeoutNanos = timeoutMap.get(method);
Method asyncMethod = methodMap.get(method);
Invokable<Object, ListenableFuture<?>> asyncMethod = methodMap.get(method);
String name = asyncMethod.getDeclaringClass().getSimpleName() + "." + asyncMethod.getName();
ListenableFuture<?> future = ((ListenableFuture<?>) asyncMethod.invoke(delegate, args));
ListenableFuture<?> future = asyncMethod.invoke(delegate, args.toArray());
if (timeoutNanos.isPresent()) {
logger.debug(">> blocking on %s for %s", name, timeoutNanos);
return future.get(timeoutNanos.get(), TimeUnit.NANOSECONDS);
@ -175,7 +178,7 @@ public final class SyncProxy extends AbstractInvocationHandler {
}
// override timeout by values configured in properties(in ms)
private Optional<Long> timeoutInNanos(Method method, Map<String, Long> timeouts) {
private Optional<Long> timeoutInNanos(Invokable<?, ?> method, Map<String, Long> timeouts) {
String className = declaring.getSimpleName();
Optional<Long> timeoutMillis = fromNullable(timeouts.get(className + "." + method.getName()))
.or(fromNullable(timeouts.get(className)))

View File

@ -133,7 +133,7 @@ public class HttpCommand {
public String toString() {
if (request instanceof GeneratedHttpRequest)
return String.format("[method=%s.%s, request=%s]", GeneratedHttpRequest.class.cast(request).getDeclaring()
.getSimpleName(), GeneratedHttpRequest.class.cast(request).getJavaMethod().getName(), request
.getSimpleName(), GeneratedHttpRequest.class.cast(request).getInvoker().getName(), request
.getRequestLine());
else
return "[request=" + request.getRequestLine() + "]";

View File

@ -21,13 +21,11 @@ package org.jclouds.internal;
import static com.google.common.base.Objects.equal;
import static com.google.common.base.Preconditions.checkNotNull;
import java.lang.reflect.Method;
import java.util.List;
import com.google.common.base.Objects;
import com.google.common.base.Objects.ToStringHelper;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.Lists;
import com.google.common.reflect.Invokable;
/**
@ -72,22 +70,6 @@ public class ClassInvokerArgs {
return self();
}
/**
* @see ClassInvokerArgs#getInvoker()
*/
@Deprecated
public B invoker(Method method) {
return invoker(Invokable.from(method));
}
/**
* @see ClassInvokerArgs#getArgs()
*/
@Deprecated
public B args(Object[] args) {
return args(args == null ? Lists.newArrayList(new Object[] { null }) : Lists.newArrayList(args));
}
/**
* @see ClassInvokerArgs#getArgs()
*/

View File

@ -21,12 +21,10 @@ package org.jclouds.rest;
import static com.google.common.base.Preconditions.checkNotNull;
import static com.google.common.collect.Collections2.filter;
import java.lang.reflect.Method;
import java.util.List;
import javax.inject.Inject;
import org.jclouds.javax.annotation.Nullable;
import org.jclouds.predicates.Validator;
import org.jclouds.rest.annotations.ParamValidators;
@ -72,12 +70,6 @@ public class InputParamValidator {
* @throws IllegalStateException
* if validation failed
*/
@Deprecated
public void validateMethodParametersOrThrow(Method method, @Nullable Object... args) {
validateMethodParametersOrThrow(Invokable.from(checkNotNull(method, "method")),
Lists.newArrayList(args));
}
public void validateMethodParametersOrThrow(Invokable<?, ?> method, List<Object> args) {
try {
performMethodValidation(checkNotNull(method, "method"), args);

View File

@ -44,9 +44,9 @@ public class BindMapToStringPayload implements MapBinder {
public <R extends HttpRequest> R bindToRequest(R request, Map<String, Object> postParams) {
checkNotNull(postParams, "postParams");
GeneratedHttpRequest r = GeneratedHttpRequest.class.cast(checkNotNull(request, "request"));
checkArgument(r.getJavaMethod().isAnnotationPresent(Payload.class),
"method %s must have @Payload annotation to use this binder", r.getJavaMethod());
String payload = r.getJavaMethod().getAnnotation(Payload.class).value();
checkArgument(r.getInvoker().isAnnotationPresent(Payload.class),
"method %s must have @Payload annotation to use this binder", r.getInvoker());
String payload = r.getInvoker().getAnnotation(Payload.class).value();
if (postParams.size() > 0) {
payload = urlDecode(expand(payload, postParams));
}

View File

@ -22,9 +22,6 @@ import static com.google.common.base.Functions.compose;
import static com.google.common.base.Throwables.propagate;
import static com.google.common.collect.Iterables.any;
import static com.google.common.collect.Iterables.find;
import static com.google.common.collect.Lists.newArrayList;
import static com.google.common.collect.Sets.difference;
import static com.google.common.util.concurrent.Callables.returning;
import static com.google.common.util.concurrent.Futures.immediateFailedFuture;
import static com.google.common.util.concurrent.Futures.transform;
import static com.google.common.util.concurrent.Futures.withFallback;
@ -80,6 +77,7 @@ import org.jclouds.internal.ClassInvokerArgs;
import org.jclouds.internal.ClassInvokerArgsAndReturnVal;
import org.jclouds.json.internal.GsonWrapper;
import org.jclouds.logging.Logger;
import org.jclouds.reflect.AbstractInvocationHandler;
import org.jclouds.rest.AuthorizationException;
import org.jclouds.rest.InvocationContext;
import org.jclouds.rest.annotations.Delegate;
@ -91,20 +89,21 @@ import org.jclouds.rest.annotations.SelectJson;
import org.jclouds.rest.annotations.Transform;
import org.jclouds.rest.annotations.Unwrap;
import org.jclouds.rest.annotations.XMLResponseParser;
import org.jclouds.rest.internal.RestAnnotationProcessor.InvokerKey;
import com.google.common.annotations.VisibleForTesting;
import com.google.common.base.Function;
import com.google.common.base.Objects;
import com.google.common.base.Optional;
import com.google.common.base.Predicate;
import com.google.common.base.Predicates;
import com.google.common.base.Supplier;
import com.google.common.cache.Cache;
import com.google.common.cache.CacheBuilder;
import com.google.common.cache.CacheLoader;
import com.google.common.cache.LoadingCache;
import com.google.common.collect.FluentIterable;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet;
import com.google.common.reflect.AbstractInvocationHandler;
import com.google.common.collect.Maps;
import com.google.common.reflect.Invokable;
import com.google.common.reflect.Parameter;
import com.google.common.reflect.TypeToken;
@ -141,6 +140,7 @@ import com.google.inject.assistedinject.Assisted;
*/
@Singleton
public abstract class AsyncRestClientProxy extends AbstractInvocationHandler {
public static interface Factory {
Declaring declaring(Class<?> declaring);
@ -181,36 +181,50 @@ public abstract class AsyncRestClientProxy extends AbstractInvocationHandler {
private final ParseSax.Factory parserFactory;
private final Class<?> declaring;
private static final LoadingCache<Class<?>, Cache<InvokerKey, Invokable<?, ?>>> delegationMapCache = CacheBuilder
.newBuilder().build(new CacheLoader<Class<?>, Cache<InvokerKey, Invokable<?, ?>>>() {
public Cache<InvokerKey, Invokable<?, ?>> load(Class<?> declaring) throws ExecutionException {
Cache<InvokerKey, Invokable<?, ?>> delegationMap = CacheBuilder.newBuilder()
.<InvokerKey, Invokable<?, ?>> build();
for (Method method : difference(ImmutableSet.copyOf(declaring.getMethods()),
ImmutableSet.copyOf(Object.class.getMethods()))) {
Invokable<?, ?> invoker = Invokable.from(method);
if (isHttpMethod(invoker) || method.isAnnotationPresent(Delegate.class)) {
delegationMap.get(new InvokerKey(invoker), returning(invoker));
} else if (!method.getDeclaringClass().equals(declaring)) { // potentially overridden
} else if (method.isAnnotationPresent(Provides.class)) {
private static final LoadingCache<Class<?>, Set<Integer>> delegationMapCache = CacheBuilder.newBuilder().build(
new CacheLoader<Class<?>, Set<Integer>>() {
public Set<Integer> load(Class<?> declaring) throws ExecutionException {
FluentIterable<Invokable<?, ?>> methodsToProcess = FluentIterable
.from(ImmutableSet.copyOf(declaring.getMethods()))
.filter(Predicates.not(Predicates.in(ImmutableSet.copyOf(Object.class.getMethods()))))
.transform(new Function<Method, Invokable<?, ?>>() {
public Invokable<?, ?> apply(Method in) {
return Invokable.from(in);
}
}
return delegationMap;
}
});
private Invokable<?, ?> getDelegateOrNull(Invokable<?, ?> in) {
return delegationMapCache.getUnchecked(declaring).getIfPresent(new InvokerKey(in));
}
private static boolean isHttpMethod(Invokable<?, ?> invoker) {
return invoker.isAnnotationPresent(Path.class) || tryFindHttpMethod(invoker).isPresent()
|| any(invoker.getParameters(), new Predicate<Parameter>() {
}).filter(new Predicate<Invokable<?, ?>>() {
public boolean apply(Invokable<?, ?> in) {
return in.isAnnotationPresent(Path.class) || tryFindHttpMethod(in).isPresent()
|| any(in.getParameters(), new Predicate<Parameter>(){
public boolean apply(Parameter in) {
return in.getType().isAssignableFrom(HttpRequest.class);
return in.getType().getRawType().isAssignableFrom(HttpRequest.class);
}
});
}
}).filter(new Predicate<Invokable<?, ?>>() {
public boolean apply(Invokable<?, ?> in) {
return in.getReturnType().getRawType().isAssignableFrom(ListenableFuture.class);
}
});
return Maps.uniqueIndex(methodsToProcess, HashSignatureExceptReturnVal.INSTANCE).keySet();
}
});
private static enum HashSignatureExceptReturnVal implements Function<Invokable<?, ?>, Integer> {
INSTANCE;
public Integer apply(Invokable<?, ?> in) {
int parametersTypeHashCode = hashParameterTypes(in);
return Objects.hashCode(in.getDeclaringClass(), in.getName(), parametersTypeHashCode);
}
}
private static int hashParameterTypes(Invokable<?, ?> in) {
int parametersTypeHashCode = 0;
for (Parameter param : in.getParameters())
parametersTypeHashCode += param.getType().hashCode();
return parametersTypeHashCode;
}
private AsyncRestClientProxy(Injector injector,
Function<ClassInvokerArgsAndReturnVal, Optional<Object>> optionalConverter, HttpCommandExecutorService http,
@ -236,12 +250,12 @@ public abstract class AsyncRestClientProxy extends AbstractInvocationHandler {
};
@Override
protected Object handleInvocation(Object proxy, Method method, Object[] args) throws ExecutionException {
protected Object handleInvocation(Object proxy, Invokable<?, ?> method, List<Object> args) throws Throwable {
if (method.isAnnotationPresent(Provides.class)) {
return lookupValueFromGuice(method);
} else if (method.isAnnotationPresent(Delegate.class)) {
return propagateContextToDelegate(method, args);
} else if (isRestCall(method)) {
} else if (isAsyncOrDelegate(method)) {
return createListenableFutureForHttpRequestMappedToMethodAndArgs(method, args);
} else {
throw new RuntimeException(String.format("Method is not annotated as either http or provider method: %s",
@ -249,12 +263,11 @@ public abstract class AsyncRestClientProxy extends AbstractInvocationHandler {
}
}
private boolean isRestCall(Method method) {
return getDelegateOrNull(Invokable.from(method)) != null
&& ListenableFuture.class.isAssignableFrom(method.getReturnType());
private boolean isAsyncOrDelegate(Invokable<?, ?> method) {
return delegationMapCache.getUnchecked(declaring).contains(HashSignatureExceptReturnVal.INSTANCE.apply(method));
}
private Object propagateContextToDelegate(Method method, Object[] args) throws ExecutionException {
private Object propagateContextToDelegate(Invokable<?, ?> method, List<Object> args) throws ExecutionException {
Class<?> asyncClass = returnTypeOrTypeOfOptional(method);
ClassInvokerArgs cma = ClassInvokerArgs.builder().clazz(asyncClass).invoker(method).args(args).build();
Object returnVal = delegateMap.get(cma);
@ -266,9 +279,9 @@ public abstract class AsyncRestClientProxy extends AbstractInvocationHandler {
return returnVal;
}
private Object lookupValueFromGuice(Method method) {
private Object lookupValueFromGuice(Invokable<?, ?> method) {
try {
Type genericReturnType = method.getGenericReturnType();
Type genericReturnType = method.getReturnType().getType();
try {
Annotation qualifier = find(ImmutableList.copyOf(method.getAnnotations()), isQualifierPresent);
return getInstanceOfTypeWithQualifier(genericReturnType, qualifier);
@ -320,15 +333,9 @@ public abstract class AsyncRestClientProxy extends AbstractInvocationHandler {
return injector.getInstance(Key.get(genericReturnType, qualifier));
}
@Deprecated
static Function<HttpResponse, ?> createResponseParser(ParseSax.Factory parserFactory, Injector injector,
Method method, HttpRequest request) {
return createResponseParser(parserFactory, injector, Invokable.from(method), request);
}
@SuppressWarnings("unchecked")
@VisibleForTesting
private static Function<HttpResponse, ?> createResponseParser(ParseSax.Factory parserFactory, Injector injector,
static Function<HttpResponse, ?> createResponseParser(ParseSax.Factory parserFactory, Injector injector,
Invokable<?, ?> method, HttpRequest request) {
Function<HttpResponse, ?> transformer;
Class<? extends HandlerWithResult<?>> handler = getSaxResponseParserClassOrNull(method);
@ -377,14 +384,8 @@ public abstract class AsyncRestClientProxy extends AbstractInvocationHandler {
return transformer;
}
private ListenableFuture<?> createListenableFutureForHttpRequestMappedToMethodAndArgs(Method method, Object[] args)
throws ExecutionException {
return createListenableFutureForHttpRequestMappedToMethodAndArgs(method, Invokable.from(method),
args == null ? newArrayList(new Object[] { null }) : newArrayList(args));
}
private ListenableFuture<?> createListenableFutureForHttpRequestMappedToMethodAndArgs(Method method,
Invokable<?, ?> invoker, List<Object> args) throws ExecutionException {
private ListenableFuture<?> createListenableFutureForHttpRequestMappedToMethodAndArgs(Invokable<?, ?> invoker,
List<Object> args) {
String name = invoker.getDeclaringClass().getSimpleName() + "." + invoker.getName();
logger.trace(">> converting %s", name);
FutureFallback<?> fallback = fallbacks.getUnchecked(invoker);
@ -394,7 +395,7 @@ public abstract class AsyncRestClientProxy extends AbstractInvocationHandler {
}
ListenableFuture<?> result;
try {
GeneratedHttpRequest request = annotationProcessor.createRequest(method, invoker, newArrayList(args));
GeneratedHttpRequest request = annotationProcessor.createRequest(invoker, args);
if (fallback instanceof InvocationContext) {
InvocationContext.class.cast(fallback).setContext(request);
}
@ -457,13 +458,9 @@ public abstract class AsyncRestClientProxy extends AbstractInvocationHandler {
private static final long serialVersionUID = 1L;
};
@Deprecated
static Key<? extends Function<HttpResponse, ?>> getParserOrThrowException(Method method) {
return getParserOrThrowException(Invokable.from(method));
}
@SuppressWarnings("unchecked")
private static Key<? extends Function<HttpResponse, ?>> getParserOrThrowException(Invokable<?, ?> method) {
@VisibleForTesting
static Key<? extends Function<HttpResponse, ?>> getParserOrThrowException(Invokable<?, ?> method) {
ResponseParser annotation = method.getAnnotation(ResponseParser.class);
if (annotation == null) {
@ -478,9 +475,9 @@ public abstract class AsyncRestClientProxy extends AbstractInvocationHandler {
} else if (method.getReturnType().equals(HttpResponse.class)
|| method.getReturnType().equals(futureHttpResponseLiteral)) {
return Key.get(Class.class.cast(IdentityFunction.class));
} else if (RestAnnotationProcessor.getAcceptHeadersOrNull(method).contains(APPLICATION_JSON)) {
} else if (RestAnnotationProcessor.getAcceptHeaders(method).contains(APPLICATION_JSON)) {
return getJsonParserKeyForMethod(method);
} else if (RestAnnotationProcessor.getAcceptHeadersOrNull(method).contains(APPLICATION_XML)
} else if (RestAnnotationProcessor.getAcceptHeaders(method).contains(APPLICATION_XML)
|| method.isAnnotationPresent(JAXBResponseParser.class)) {
return getJAXBParserKeyForMethod(method);
} else if (method.getReturnType().equals(String.class) || method.getReturnType().equals(futureStringLiteral)) {

View File

@ -20,7 +20,6 @@ package org.jclouds.rest.internal;
import static com.google.common.base.Preconditions.checkNotNull;
import java.lang.reflect.Method;
import java.net.URI;
import java.util.Arrays;
import java.util.Collections;
@ -54,7 +53,6 @@ public class GeneratedHttpRequest extends HttpRequest {
public static class Builder extends HttpRequest.Builder<Builder> {
protected Class<?> declaring;
protected Method javaMethod;
protected Invokable<?, ?> invoker;
// args can be null, so cannot use immutable list
protected List<Object> args = Lists.newArrayList();
@ -68,16 +66,6 @@ public class GeneratedHttpRequest extends HttpRequest {
return this;
}
/**
* @see GeneratedHttpRequest#getJavaMethod()
*/
@Deprecated
public Builder javaMethod(Method javaMethod) {
this.javaMethod = checkNotNull(javaMethod, "javaMethod");
this.invoker(Invokable.from(javaMethod));
return this;
}
/**
* @see GeneratedHttpRequest#getInvoker()
*/
@ -118,14 +106,13 @@ public class GeneratedHttpRequest extends HttpRequest {
}
public GeneratedHttpRequest build() {
return new GeneratedHttpRequest(method, endpoint, headers.build(), payload, declaring, javaMethod, invoker,
args, filters.build(), caller);
return new GeneratedHttpRequest(method, endpoint, headers.build(), payload, declaring, invoker, args,
filters.build(), caller);
}
public Builder fromGeneratedHttpRequest(GeneratedHttpRequest in) {
return super.fromHttpRequest(in)
.declaring(in.getDeclaring())
.javaMethod(in.getJavaMethod())
.invoker(in.invoker)
.args(in.getArgs())
.caller(in.getCaller().orNull());
@ -138,20 +125,18 @@ public class GeneratedHttpRequest extends HttpRequest {
}
private final Class<?> declaring;
private final Method javaMethod;
private final Invokable<?, ?> invoker;
private final List<Object> args;
private final Optional<ClassInvokerArgs> caller;
protected GeneratedHttpRequest(String method, URI endpoint, Multimap<String, String> headers,
@Nullable Payload payload, Class<?> declaring, Method javaMethod, Invokable<?, ?> invoker,
Iterable<Object> args, Iterable<HttpRequestFilter> filters, Optional<ClassInvokerArgs> caller) {
@Nullable Payload payload, Class<?> declaring, Invokable<?, ?> invoker,
List<Object> args, Iterable<HttpRequestFilter> filters, Optional<ClassInvokerArgs> caller) {
super(method, endpoint, headers, payload, filters);
this.declaring = checkNotNull(declaring, "declaring");
this.javaMethod = checkNotNull(javaMethod, "javaMethod");
this.invoker = checkNotNull(invoker, "invoker");
// TODO make immutable. ImmutableList.of() doesn't accept nulls
this.args = Lists.newArrayList(checkNotNull(args, "args"));
this.args = Collections.unmodifiableList(checkNotNull(args, "args"));
this.caller = checkNotNull(caller, "caller");
}
@ -159,20 +144,12 @@ public class GeneratedHttpRequest extends HttpRequest {
return declaring;
}
/**
* @deprecated see {@link #getInvoker()}
*/
@Deprecated
public Method getJavaMethod() {
return javaMethod;
}
public Invokable<?,?> getInvoker() {
return invoker;
}
public List<Object> getArgs() {
return Collections.unmodifiableList(args);
return args;
}
public Optional<ClassInvokerArgs> getCaller() {

View File

@ -18,7 +18,6 @@
*/
package org.jclouds.rest.internal;
import static com.google.common.base.Functions.toStringFunction;
import static com.google.common.base.Objects.equal;
import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkNotNull;
import static com.google.common.base.Preconditions.checkState;
@ -44,7 +43,6 @@ import static org.jclouds.util.Strings2.replaceTokens;
import java.lang.annotation.Annotation;
import java.lang.reflect.Array;
import java.lang.reflect.Method;
import java.net.URI;
import java.util.Collection;
import java.util.LinkedHashMap;
@ -104,7 +102,6 @@ import org.jclouds.rest.binders.BindToJsonPayloadWrappedWith;
import com.google.common.annotations.VisibleForTesting;
import com.google.common.base.Function;
import com.google.common.base.Objects;
import com.google.common.base.Optional;
import com.google.common.base.Predicate;
import com.google.common.base.Supplier;
@ -118,7 +115,6 @@ import com.google.common.collect.ImmutableSet;
import com.google.common.collect.ImmutableSet.Builder;
import com.google.common.collect.LinkedHashMultimap;
import com.google.common.collect.LinkedListMultimap;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.google.common.collect.Multimap;
import com.google.common.primitives.Chars;
@ -194,15 +190,6 @@ public abstract class RestAnnotationProcessor {
@Resource
protected Logger logger = Logger.NULL;
static final LoadingCache<Method, Invokable<?, ?>> methods = CacheBuilder.newBuilder().build(
new CacheLoader<Method, Invokable<?, ?>>() {
@Override
public Invokable<?, ?> load(Method method) {
return Invokable.from(method);
}
});
private static final Function<? super Entry<String, Object>, ? extends Part> ENTRY_TO_PART = new Function<Entry<String, Object>, Part>() {
@Override
public Part apply(Entry<String, Object> from) {
@ -230,44 +217,7 @@ public abstract class RestAnnotationProcessor {
this.declaring = declaring;
}
public static class InvokerKey {
private final String name;
private final int parametersTypeHashCode;
private final Class<?> declaringClass;
public InvokerKey(Invokable<?, ?> invoker) {
this.name = invoker.getName();
this.declaringClass = invoker.getDeclaringClass();
int parametersTypeHashCode = 0;
for (Parameter param : invoker.getParameters())
parametersTypeHashCode += param.getType().hashCode();
this.parametersTypeHashCode = parametersTypeHashCode;
}
@Override
public int hashCode() {
return Objects.hashCode(declaringClass, name, parametersTypeHashCode);
}
@Override
public boolean equals(Object obj) {
if (this == obj) return true;
if (obj == null || getClass() != obj.getClass()) return false;
InvokerKey that = InvokerKey.class.cast(obj);
return equal(this.declaringClass, that.declaringClass)
&& equal(this.name, that.name)
&& equal(this.parametersTypeHashCode, that.parametersTypeHashCode);
}
}
@Deprecated
public GeneratedHttpRequest createRequest(Method method, @Nullable Object... args) {
List<Object> list = args == null ? Lists.newArrayList(new Object[] { null }) : Lists.newArrayList(args);
return createRequest(method, methods.getUnchecked(method), list);
}
public GeneratedHttpRequest createRequest(Method method, Invokable<?, ?> invoker, List<Object> args) {
checkNotNull(method, "method");
public GeneratedHttpRequest createRequest(Invokable<?, ?> invoker, List<Object> args) {
checkNotNull(invoker, "invoker");
checkNotNull(args, "args");
inputParamValidator.validateMethodParametersOrThrow(invoker, args);
@ -293,7 +243,6 @@ public abstract class RestAnnotationProcessor {
}
requestBuilder.declaring(declaring)
.javaMethod(method)
.invoker(invoker)
.args(args)
.filters(getFiltersIfAnnotated(invoker));
@ -550,13 +499,8 @@ public abstract class RestAnnotationProcessor {
return filters;
}
@Deprecated
public static URI getEndpointInParametersOrNull(Method method, @Deprecated Object[] args, Injector injector) {
return getEndpointInParametersOrNull(methods.getUnchecked(method), args != null ? Lists.newArrayList(args)
: ImmutableList.of(), injector);
}
private static URI getEndpointInParametersOrNull(Invokable<?,?> method, List<Object> args, Injector injector) {
@VisibleForTesting
static URI getEndpointInParametersOrNull(Invokable<?,?> method, List<Object> args, Injector injector) {
Collection<Parameter> endpointParams = parametersWithAnnotation(method, EndpointParam.class);
if (endpointParams.isEmpty())
return null;
@ -603,7 +547,6 @@ public abstract class RestAnnotationProcessor {
}
@VisibleForTesting
@Deprecated
static URI addHostIfMissing(URI original, URI withHost) {
checkNotNull(withHost, "URI withHost cannot be null");
checkArgument(withHost.getHost() != null, "URI withHost must have host:" + withHost);
@ -740,12 +683,6 @@ public abstract class RestAnnotationProcessor {
return result.build();
}
@Deprecated
public Multimap<String, String> buildHeaders(Multimap<String, ?> tokenValues, Method method, Object... args) {
return buildHeaders(tokenValues, methods.getUnchecked(method), args != null ? Lists.newArrayList(args)
: ImmutableList.of());
}
private Multimap<String, String> buildHeaders(Multimap<String, ?> tokenValues, Invokable<?, ?> method,
List<Object> args) {
Multimap<String, String> headers = LinkedHashMultimap.create();
@ -762,24 +699,16 @@ public abstract class RestAnnotationProcessor {
}
private void addConsumesIfPresentOnTypeOrMethod(Multimap<String, String> headers, Invokable<?,?> method) {
List<String> accept = getAcceptHeadersOrNull(method);
if (accept.size() > 0)
Set<String> accept = getAcceptHeaders(method);
if (!accept.isEmpty())
headers.replaceValues(ACCEPT, accept);
}
// TODO: refactor this out
@VisibleForTesting
static List<String> getAcceptHeadersOrNull(Invokable<?,?> method) {
List<String> accept = ImmutableList.of();
if (method.getDeclaringClass().isAnnotationPresent(Consumes.class)) {
Consumes header = method.getDeclaringClass().getAnnotation(Consumes.class);
accept = asList(header.value());
}
if (method.isAnnotationPresent(Consumes.class)) {
Consumes header = method.getAnnotation(Consumes.class);
accept = asList(header.value());
}
return accept;
static Set<String> getAcceptHeaders(Invokable<?, ?> method) {
Optional<Consumes> accept = Optional.fromNullable(method.getAnnotation(Consumes.class)).or(
Optional.fromNullable(method.getDeclaringClass().getAnnotation(Consumes.class)));
return (accept.isPresent()) ? ImmutableSet.copyOf(accept.get().value()) : ImmutableSet.<String> of();
}
private void addProducesIfPresentOnTypeOrMethod(Multimap<String, String> headers, Invokable<?,?> method) {

View File

@ -18,7 +18,6 @@
*/
package org.jclouds.util;
import java.lang.reflect.Method;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.lang.reflect.WildcardType;
@ -37,12 +36,6 @@ public class Optionals2 {
return returnTypeOrTypeOfOptional(type.getRawType(), type.getType());
}
public static Class<?> returnTypeOrTypeOfOptional(Method method) {
Class<?> syncClass = method.getReturnType();
Type genericType = method.getGenericReturnType();
return returnTypeOrTypeOfOptional(syncClass, genericType);
}
private static Class<?> returnTypeOrTypeOfOptional(Class<?> syncClass, Type genericType) {
if (syncClass.isAssignableFrom(Optional.class)) {
ParameterizedType futureType = ParameterizedType.class.cast(genericType);
@ -57,8 +50,7 @@ public class Optionals2 {
return syncClass;
}
public static boolean isReturnTypeOptional(Method method) {
return method.getReturnType().isAssignableFrom(Optional.class);
public static boolean isReturnTypeOptional(Invokable<?, ?> method) {
return method.getReturnType().getRawType().isAssignableFrom(Optional.class);
}
}

View File

@ -34,6 +34,7 @@ import org.jclouds.rest.ResourceNotFoundException;
import com.google.common.annotations.VisibleForTesting;
import com.google.common.base.Predicate;
import com.google.common.base.Throwables;
import com.google.common.reflect.TypeToken;
import com.google.inject.CreationException;
import com.google.inject.ProvisionException;
import com.google.inject.spi.Message;
@ -120,10 +121,10 @@ public class Throwables2 {
// Note this needs to be kept up-to-date with all top-level exceptions jclouds works against
@SuppressWarnings( { "unchecked", "rawtypes" })
public static Exception returnFirstExceptionIfInListOrThrowStandardExceptionOrCause(Class[] exceptionTypes,
public static Exception returnFirstExceptionIfInListOrThrowStandardExceptionOrCause(Iterable<TypeToken<? extends Throwable>> throwables,
Exception exception) throws Exception {
for (Class type : exceptionTypes) {
Throwable throwable = getFirstThrowableOfType(exception, type);
for (TypeToken<? extends Throwable> type : throwables) {
Throwable throwable = getFirstThrowableOfType(exception, (Class<Throwable>) type.getRawType());
if (throwable != null) {
return (Exception) throwable;
}

View File

@ -23,7 +23,6 @@ import static org.testng.Assert.assertTrue;
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Method;
import java.util.Properties;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
@ -50,6 +49,8 @@ import org.testng.annotations.BeforeTest;
import org.testng.annotations.Test;
import com.google.common.base.Supplier;
import com.google.common.collect.ImmutableList;
import com.google.common.reflect.Invokable;
@Test(groups = "unit", testName = "BackoffLimitedRetryHandlerTest")
public class BackoffLimitedRetryHandlerTest {
@ -169,9 +170,9 @@ public class BackoffLimitedRetryHandlerTest {
.getInstance(RestAnnotationProcessor.Factory.class).declaring(IntegrationTestAsyncClient.class);
private HttpCommand createCommand() throws SecurityException, NoSuchMethodException {
Method method = IntegrationTestAsyncClient.class.getMethod("download", String.class);
Invokable<?, Object> method = Invokable.from(IntegrationTestAsyncClient.class.getMethod("download", String.class));
return new HttpCommand(processor.createRequest(method, "1"));
return new HttpCommand(processor.createRequest(method, ImmutableList.<Object> of("1")));
}
@Test

View File

@ -18,7 +18,6 @@
*/
package org.jclouds.http.internal;
import java.lang.reflect.Method;
import java.util.Collection;
import java.util.List;
import java.util.concurrent.ExecutorService;
@ -42,6 +41,7 @@ import org.jclouds.rest.internal.GeneratedHttpRequest;
import com.google.common.base.Supplier;
import com.google.common.collect.Iterables;
import com.google.common.reflect.Invokable;
import com.google.inject.AbstractModule;
import com.google.inject.Module;
import com.google.inject.TypeLiteral;
@ -73,16 +73,15 @@ public class TrackingJavaUrlHttpCommandExecutorService extends JavaUrlHttpComman
};
}
public static Method getJavaMethodForRequestAtIndex(final Collection<HttpCommand> commandsInvoked, int index) {
return getJavaMethodForRequest(Iterables.get(commandsInvoked, index));
public static Invokable<?, ?> getInvokerOfRequestAtIndex(final Collection<HttpCommand> commandsInvoked, int index) {
return getInvokerOfRequest(Iterables.get(commandsInvoked, index));
}
public static Method getJavaMethodForRequest(HttpCommand commandInvoked) {
return GeneratedHttpRequest.class.cast(commandInvoked.getCurrentRequest()).getJavaMethod();
public static Invokable<?, ?> getInvokerOfRequest(HttpCommand commandInvoked) {
return GeneratedHttpRequest.class.cast(commandInvoked.getCurrentRequest()).getInvoker();
}
@SuppressWarnings("unchecked")
public static List<Object> getJavaArgsForRequestAtIndex(final Collection<HttpCommand> commandsInvoked, int index) {
public static List<Object> getArgsForRequestAtIndex(final Collection<HttpCommand> commandsInvoked, int index) {
return GeneratedHttpRequest.class.cast(Iterables.get(commandsInvoked, index).getCurrentRequest()).getArgs();
}

View File

@ -18,8 +18,6 @@
*/
package org.jclouds.rest;
import java.lang.reflect.Method;
import javax.ws.rs.POST;
import javax.ws.rs.PathParam;
@ -34,6 +32,8 @@ import org.testng.TestException;
import org.testng.annotations.BeforeClass;
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")
@ -58,26 +58,26 @@ public class InputParamValidatorTest {
*/
@Test
public void testInputParamsValidation() throws Exception {
Method allParamsValidatedMethod = InputParamValidatorForm.class.getMethod("allParamsValidated", String.class,
String.class);
Method oneParamValidatedMethod = InputParamValidatorForm.class.getMethod("oneParamValidated", String.class,
String.class);
Invokable<?, ?> allParamsValidatedMethod = Invokable.from(InputParamValidatorForm.class.getMethod(
"allParamsValidated", String.class, String.class));
Invokable<?, ?> oneParamValidatedMethod = Invokable.from(InputParamValidatorForm.class.getMethod(
"oneParamValidated", String.class, String.class));
RestAnnotationProcessor restAnnotationProcessor = factory(InputParamValidatorForm.class);
restAnnotationProcessor.createRequest(allParamsValidatedMethod, "blah", "blah");
restAnnotationProcessor.createRequest(oneParamValidatedMethod, "blah", "blah");
restAnnotationProcessor.createRequest(allParamsValidatedMethod, ImmutableList.<Object> of("blah", "blah"));
restAnnotationProcessor.createRequest(oneParamValidatedMethod, ImmutableList.<Object> of("blah", "blah"));
try {
restAnnotationProcessor.createRequest(allParamsValidatedMethod, "BLAH", "blah");
restAnnotationProcessor.createRequest(allParamsValidatedMethod, ImmutableList.<Object> of("BLAH", "blah"));
throw new TestException(
"AllLowerCaseValidator shouldn't have passed 'BLAH' as a parameter because it's uppercase.");
} catch (IllegalArgumentException e) {
// supposed to happen - continue
}
restAnnotationProcessor.createRequest(oneParamValidatedMethod, "BLAH", "blah");
restAnnotationProcessor.createRequest(oneParamValidatedMethod, ImmutableList.<Object> of("BLAH", "blah"));
try {
restAnnotationProcessor.createRequest(oneParamValidatedMethod, "blah", "BLAH");
restAnnotationProcessor.createRequest(oneParamValidatedMethod, ImmutableList.<Object> of("blah", "BLAH"));
throw new TestException(
"AllLowerCaseValidator shouldn't have passed 'BLAH' as the second parameter because it's uppercase.");
} catch (IllegalArgumentException e) {
@ -98,8 +98,8 @@ public class InputParamValidatorTest {
@Test(expectedExceptions = ClassCastException.class)
public void testWrongPredicateTypeLiteral() throws Exception {
Method method = WrongValidator.class.getMethod("method", Integer.class);
new InputParamValidator(injector).validateMethodParametersOrThrow(method, 55);
Invokable<?, ?> method = Invokable.from(WrongValidator.class.getMethod("method", Integer.class));
new InputParamValidator(injector).validateMethodParametersOrThrow(method, ImmutableList.<Object> of(55));
}
private RestAnnotationProcessor factory(Class<?> clazz) {

View File

@ -21,7 +21,6 @@ package org.jclouds.rest.binders;
import static org.testng.Assert.assertEquals;
import java.io.File;
import java.lang.reflect.Method;
import javax.ws.rs.PathParam;
@ -33,6 +32,7 @@ import org.testng.annotations.Test;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.common.reflect.Invokable;
/**
* Tests behavior of {@code BindMapToStringPayload}
@ -53,9 +53,9 @@ public class BindMapToStringPayloadTest {
@Test
public void testCorrect() throws SecurityException, NoSuchMethodException {
Method testPayload = TestPayload.class.getMethod("testPayload", String.class);
Invokable<?, Object> testPayload = Invokable.from(TestPayload.class.getMethod("testPayload", String.class));
GeneratedHttpRequest request = GeneratedHttpRequest.builder()
.declaring(TestPayload.class).javaMethod(testPayload).args(ImmutableList.<Object> of("robot"))
.declaring(TestPayload.class).invoker(testPayload).args(ImmutableList.<Object> of("robot"))
.method("POST").endpoint("http://localhost").build();
GeneratedHttpRequest newRequest = binder()
@ -67,9 +67,9 @@ public class BindMapToStringPayloadTest {
@Test
public void testDecodes() throws SecurityException, NoSuchMethodException {
Method testPayload = TestPayload.class.getMethod("changeAdminPass", String.class);
Invokable<?, Object> testPayload = Invokable.from(TestPayload.class.getMethod("changeAdminPass", String.class));
GeneratedHttpRequest request = GeneratedHttpRequest.builder()
.declaring(TestPayload.class).javaMethod(testPayload).args(ImmutableList.<Object> of("foo"))
.declaring(TestPayload.class).invoker(testPayload).args(ImmutableList.<Object> of("foo"))
.method("POST").endpoint("http://localhost").build();
GeneratedHttpRequest newRequest = binder()
@ -81,9 +81,9 @@ public class BindMapToStringPayloadTest {
@Test(expectedExceptions = IllegalArgumentException.class)
public void testMustHavePayloadAnnotation() throws SecurityException, NoSuchMethodException {
Method noPayload = TestPayload.class.getMethod("noPayload", String.class);
Invokable<?, Object> noPayload = Invokable.from(TestPayload.class.getMethod("noPayload", String.class));
GeneratedHttpRequest request = GeneratedHttpRequest.builder()
.declaring(TestPayload.class).javaMethod(noPayload).args(ImmutableList.<Object> of("robot"))
.declaring(TestPayload.class).invoker(noPayload).args(ImmutableList.<Object> of("robot"))
.method("POST").endpoint("http://localhost").build();
binder().bindToRequest(request, ImmutableMap.<String,Object>of("fooble", "robot"));
}

View File

@ -33,6 +33,8 @@ 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
@ -163,8 +165,8 @@ public class PresentWhenApiVersionLexicographicallyAtOrAfterSinceApiVersionTest
ClassInvokerArgsAndReturnVal getApi(String name, Class<?> type) {
try {
return ClassInvokerArgsAndReturnVal.builder().clazz(type)
.invoker(EC2AsyncApi.class.getDeclaredMethod("get" + name + "ApiForRegion", String.class))
.args(new Object[] { "region" }).returnVal("present").build();
.invoker(Invokable.from(EC2AsyncApi.class.getDeclaredMethod("get" + name + "ApiForRegion", String.class)))
.args(ImmutableList.<Object> of("region")).returnVal("present").build();
} catch (Exception e) {
throw propagate(e);
}

View File

@ -26,7 +26,6 @@ import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertNull;
import java.io.IOException;
import java.lang.reflect.Method;
import java.util.Date;
import java.util.Map.Entry;
import java.util.concurrent.ExecutorService;
@ -49,6 +48,7 @@ import org.testng.annotations.Test;
import com.google.common.collect.Multimap;
import com.google.common.collect.SortedSetMultimap;
import com.google.common.collect.TreeMultimap;
import com.google.common.reflect.Invokable;
import com.google.inject.AbstractModule;
import com.google.inject.Injector;
import com.google.inject.name.Names;
@ -160,7 +160,7 @@ public abstract class BaseRestApiTest {
assertEquals(request.getRequestLine(), toMatch);
}
protected void assertFallbackClassEquals(Method method, @Nullable Class<?> expected) {
protected void assertFallbackClassEquals(Invokable<?, ?> method, @Nullable Class<?> expected) {
Fallback fallbackAnnotation = method.getAnnotation(Fallback.class);
Class<?> assigned = fallbackAnnotation != null ? fallbackAnnotation.value() : MapHttp4xxCodesToExceptions.class;
if (expected == null)
@ -169,13 +169,13 @@ public abstract class BaseRestApiTest {
assertEquals(assigned, expected);
}
protected void assertSaxResponseParserClassEquals(Method method, @Nullable Class<?> parserClass) {
protected void assertSaxResponseParserClassEquals(Invokable<?, ?> method, @Nullable Class<?> parserClass) {
XMLResponseParser annotation = method.getAnnotation(XMLResponseParser.class);
Class<?> expected = (annotation != null) ? annotation.value() :null;
assertEquals(expected, parserClass);
}
protected void assertResponseParserClassEquals(Method method, HttpRequest request, @Nullable Class<?> parserClass) {
protected void assertResponseParserClassEquals(Invokable<?, ?> method, HttpRequest request, @Nullable Class<?> parserClass) {
assertEquals(AsyncRestClientProxy.createResponseParser(parserFactory, injector, method, request).getClass(), parserClass);
}

View File

@ -22,11 +22,10 @@ import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertFalse;
import static org.testng.Assert.assertTrue;
import java.lang.reflect.Method;
import org.testng.annotations.Test;
import com.google.common.base.Optional;
import com.google.common.reflect.Invokable;
/**
* @author Adrian Cole
@ -41,25 +40,25 @@ public class Optionals2Test {
}
public void testReturnTypeOrTypeOfOptionalWhenOptional() throws SecurityException, NoSuchMethodException {
Method method = Test.class.getMethod("getOptional");
Invokable<?, ?> method = Invokable.from(Test.class.getMethod("getOptional"));
assertEquals(Optionals2.returnTypeOrTypeOfOptional(method), String.class);
}
public void testReturnTypeOrTypeOfOptionalWhenNotOptional() throws SecurityException, NoSuchMethodException {
Method method = Test.class.getMethod("getNotOptional");
Invokable<?, ?> method = Invokable.from(Test.class.getMethod("getNotOptional"));
assertEquals(Optionals2.returnTypeOrTypeOfOptional(method), String.class);
}
public void testIsReturnTypeOptionalWhenOptional() throws SecurityException, NoSuchMethodException {
Method method = Test.class.getMethod("getOptional");
Invokable<?, ?> method = Invokable.from(Test.class.getMethod("getOptional"));
assertTrue(Optionals2.isReturnTypeOptional(method));
}
public void testIsReturnTypeOptionalWhenNotOptional() throws SecurityException, NoSuchMethodException {
Method method = Test.class.getMethod("getNotOptional");
Invokable<?, ?> method = Invokable.from(Test.class.getMethod("getNotOptional"));
assertFalse(Optionals2.isReturnTypeOptional(method));
}

View File

@ -26,8 +26,8 @@ import static org.testng.Assert.assertEquals;
import java.io.IOException;
import java.net.SocketException;
import java.util.Map;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;
import java.util.concurrent.TimeoutException;
import org.jclouds.concurrent.TransformParallelException;
@ -41,6 +41,7 @@ import org.testng.annotations.Test;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
import com.google.common.reflect.TypeToken;
import com.google.inject.CreationException;
import com.google.inject.ProvisionException;
import com.google.inject.spi.Message;
@ -117,153 +118,160 @@ public class Throwables2Test {
assertEquals(getFirstThrowableOfType(pex, AuthorizationException.class), null);
}
@SuppressWarnings("unchecked")
public void testGetCauseTransformParallel() {
Exception aex = createMock(AuthorizationException.class);
TransformParallelException pex = new TransformParallelException((Map) ImmutableMap.of(), ImmutableMap.of("bad",
aex), "test");
TransformParallelException pex = new TransformParallelException(ImmutableMap.<Object, Future<?>> of(),
ImmutableMap.of("bad", aex), "test");
assertEquals(getFirstThrowableOfType(pex, AuthorizationException.class), aex);
}
@SuppressWarnings("unchecked")
public void testGetFirstThrowableOfTypeInnerTransformParallel() {
Exception aex = createMock(AuthorizationException.class);
TransformParallelException pex = new TransformParallelException((Map) ImmutableMap.of(), ImmutableMap.of("bad",
(Exception) new ExecutionException(aex)), "test");
TransformParallelException pex = new TransformParallelException(ImmutableMap.<Object, Future<?>> of(),
ImmutableMap.of("bad", (Exception) new ExecutionException(aex)), "test");
assertEquals(getFirstThrowableOfType(pex, AuthorizationException.class), aex);
}
@SuppressWarnings("unchecked")
public void testGetFirstThrowableOfTypeOuterTransformParallel() {
Exception aex = createMock(AuthorizationException.class);
TransformParallelException pex = new TransformParallelException((Map) ImmutableMap.of(), ImmutableMap.of("bad",
(Exception) aex), "test");
TransformParallelException pex = new TransformParallelException(ImmutableMap.<Object, Future<?>> of(),
ImmutableMap.of("bad", (Exception) aex), "test");
assertEquals(getFirstThrowableOfType(new ExecutionException(pex), AuthorizationException.class), aex);
}
@SuppressWarnings("unchecked")
public void testGetFirstThrowableOfTypeFailTransformParallel() {
Exception aex = createMock(TimeoutException.class);
TransformParallelException pex = new TransformParallelException((Map) ImmutableMap.of(), ImmutableMap.of("bad",
aex), "test");
TransformParallelException pex = new TransformParallelException(ImmutableMap.<Object, Future<?>> of(),
ImmutableMap.of("bad", aex), "test");
assertEquals(getFirstThrowableOfType(pex, AuthorizationException.class), null);
}
@Test
public void testReturnExceptionThatsInList() throws Exception {
Exception e = new TestException();
assertEquals(returnFirstExceptionIfInListOrThrowStandardExceptionOrCause(new Class[] { TestException.class }, e),
e);
assertEquals(returnFirstExceptionIfInListOrThrowStandardExceptionOrCause(new Class[] { TestException.class },
assertEquals(
returnFirstExceptionIfInListOrThrowStandardExceptionOrCause(
ImmutableSet.<TypeToken<? extends Throwable>> of(TypeToken.of(TestException.class)), e), e);
assertEquals(
returnFirstExceptionIfInListOrThrowStandardExceptionOrCause(
ImmutableSet.<TypeToken<? extends Throwable>> of(TypeToken.of(TestException.class)),
new RuntimeException(e)), e);
}
@Test(expectedExceptions = TestException.class)
public void testThrowExceptionNotInList() throws Exception {
Exception e = new TestException();
returnFirstExceptionIfInListOrThrowStandardExceptionOrCause(new Class[] {}, e);
returnFirstExceptionIfInListOrThrowStandardExceptionOrCause(ImmutableSet.<TypeToken<? extends Throwable>> of(), e);
}
@Test(expectedExceptions = IllegalStateException.class)
public void testPropagateStandardExceptionIllegalStateException() throws Exception {
Exception e = new IllegalStateException();
returnFirstExceptionIfInListOrThrowStandardExceptionOrCause(new Class[] {}, new RuntimeException(e));
returnFirstExceptionIfInListOrThrowStandardExceptionOrCause(ImmutableSet.<TypeToken<? extends Throwable>> of(),
new RuntimeException(e));
}
@Test(expectedExceptions = IllegalArgumentException.class)
public void testPropagateStandardExceptionIllegalArgumentException() throws Exception {
Exception e = new IllegalArgumentException();
returnFirstExceptionIfInListOrThrowStandardExceptionOrCause(new Class[] {}, new RuntimeException(e));
returnFirstExceptionIfInListOrThrowStandardExceptionOrCause(ImmutableSet.<TypeToken<? extends Throwable>> of(),
new RuntimeException(e));
}
@Test(expectedExceptions = UnsupportedOperationException.class)
public void testPropagateStandardExceptionUnsupportedOperationException() throws Exception {
Exception e = new UnsupportedOperationException();
returnFirstExceptionIfInListOrThrowStandardExceptionOrCause(new Class[] {}, new RuntimeException(e));
returnFirstExceptionIfInListOrThrowStandardExceptionOrCause(ImmutableSet.<TypeToken<? extends Throwable>> of(),
new RuntimeException(e));
}
@Test(expectedExceptions = AssertionError.class)
public void testPropagateStandardExceptionAssertionError() throws Exception {
AssertionError e = new AssertionError();
returnFirstExceptionIfInListOrThrowStandardExceptionOrCause(new Class[] {}, new RuntimeException(e));
returnFirstExceptionIfInListOrThrowStandardExceptionOrCause(ImmutableSet.<TypeToken<? extends Throwable>> of(),
new RuntimeException(e));
}
@Test(expectedExceptions = AuthorizationException.class)
public void testPropagateStandardExceptionAuthorizationException() throws Exception {
Exception e = new AuthorizationException();
returnFirstExceptionIfInListOrThrowStandardExceptionOrCause(new Class[] {}, new RuntimeException(e));
returnFirstExceptionIfInListOrThrowStandardExceptionOrCause(ImmutableSet.<TypeToken<? extends Throwable>> of(),
new RuntimeException(e));
}
@Test(expectedExceptions = AuthorizationException.class)
public void testPropagateProvisionExceptionAuthorizationException() throws Exception {
Exception e = new AuthorizationException();
returnFirstExceptionIfInListOrThrowStandardExceptionOrCause(new Class[] {}, new ProvisionException(ImmutableSet.of(new Message(
ImmutableList.of(), "Error in custom provider",e))));
returnFirstExceptionIfInListOrThrowStandardExceptionOrCause(ImmutableSet.<TypeToken<? extends Throwable>> of(),
new ProvisionException(ImmutableSet.of(new Message(ImmutableList.of(), "Error in custom provider", e))));
}
@Test(expectedExceptions = AuthorizationException.class)
public void testPropagateCreationExceptionAuthorizationException() throws Exception {
Exception e = new AuthorizationException();
returnFirstExceptionIfInListOrThrowStandardExceptionOrCause(new Class[] {}, new CreationException(ImmutableSet.of(new Message(
ImmutableList.of(), "Error in custom provider",e))));
returnFirstExceptionIfInListOrThrowStandardExceptionOrCause(ImmutableSet.<TypeToken<? extends Throwable>> of(),
new CreationException(ImmutableSet.of(new Message(ImmutableList.of(), "Error in custom provider", e))));
}
@Test(expectedExceptions = InsufficientResourcesException.class)
public void testPropagateStandardExceptionInsufficientResourcesException() throws Exception {
Exception e = new InsufficientResourcesException();
returnFirstExceptionIfInListOrThrowStandardExceptionOrCause(new Class[] {}, new RuntimeException(e));
returnFirstExceptionIfInListOrThrowStandardExceptionOrCause(ImmutableSet.<TypeToken<? extends Throwable>> of(),
new RuntimeException(e));
}
@Test(expectedExceptions = ResourceNotFoundException.class)
public void testPropagateStandardExceptionResourceNotFoundException() throws Exception {
Exception e = new ResourceNotFoundException();
returnFirstExceptionIfInListOrThrowStandardExceptionOrCause(new Class[] {}, new RuntimeException(e));
returnFirstExceptionIfInListOrThrowStandardExceptionOrCause(ImmutableSet.<TypeToken<? extends Throwable>> of(),
new RuntimeException(e));
}
@Test(expectedExceptions = IllegalStateException.class)
public void testPropagateStandardExceptionIllegalStateExceptionNestedInHttpResponseException() throws Exception {
Exception e = new IllegalStateException();
returnFirstExceptionIfInListOrThrowStandardExceptionOrCause(new Class[] {}, new HttpResponseException("goo",
createNiceMock(HttpCommand.class), null, e));
returnFirstExceptionIfInListOrThrowStandardExceptionOrCause(ImmutableSet.<TypeToken<? extends Throwable>> of(),
new HttpResponseException("goo", createNiceMock(HttpCommand.class), null, e));
}
@Test(expectedExceptions = IllegalArgumentException.class)
public void testPropagateStandardExceptionIllegalArgumentExceptionNestedInHttpResponseException() throws Exception {
Exception e = new IllegalArgumentException();
returnFirstExceptionIfInListOrThrowStandardExceptionOrCause(new Class[] {}, new HttpResponseException("goo",
createNiceMock(HttpCommand.class), null, e));
returnFirstExceptionIfInListOrThrowStandardExceptionOrCause(ImmutableSet.<TypeToken<? extends Throwable>> of(),
new HttpResponseException("goo", createNiceMock(HttpCommand.class), null, e));
}
@Test(expectedExceptions = UnsupportedOperationException.class)
public void testPropagateStandardExceptionUnsupportedOperationExceptionNestedInHttpResponseException()
throws Exception {
Exception e = new UnsupportedOperationException();
returnFirstExceptionIfInListOrThrowStandardExceptionOrCause(new Class[] {}, new HttpResponseException("goo",
createNiceMock(HttpCommand.class), null, e));
returnFirstExceptionIfInListOrThrowStandardExceptionOrCause(ImmutableSet.<TypeToken<? extends Throwable>> of(),
new HttpResponseException("goo", createNiceMock(HttpCommand.class), null, e));
}
@Test(expectedExceptions = AuthorizationException.class)
public void testPropagateStandardExceptionAuthorizationExceptionNestedInHttpResponseException() throws Exception {
Exception e = new AuthorizationException();
returnFirstExceptionIfInListOrThrowStandardExceptionOrCause(new Class[] {}, new HttpResponseException("goo",
createNiceMock(HttpCommand.class), null, e));
returnFirstExceptionIfInListOrThrowStandardExceptionOrCause(ImmutableSet.<TypeToken<? extends Throwable>> of(),
new HttpResponseException("goo", createNiceMock(HttpCommand.class), null, e));
}
@Test(expectedExceptions = ResourceNotFoundException.class)
public void testPropagateStandardExceptionResourceNotFoundExceptionNestedInHttpResponseException() throws Exception {
Exception e = new ResourceNotFoundException();
returnFirstExceptionIfInListOrThrowStandardExceptionOrCause(new Class[] {}, new HttpResponseException("goo",
createNiceMock(HttpCommand.class), null, e));
returnFirstExceptionIfInListOrThrowStandardExceptionOrCause(ImmutableSet.<TypeToken<? extends Throwable>> of(),
new HttpResponseException("goo", createNiceMock(HttpCommand.class), null, e));
}
@Test(expectedExceptions = HttpResponseException.class)
public void testPropagateStandardExceptionHttpResponseException() throws Exception {
Exception e = new HttpResponseException("goo", createNiceMock(HttpCommand.class), null);
returnFirstExceptionIfInListOrThrowStandardExceptionOrCause(new Class[] {}, new RuntimeException(e));
returnFirstExceptionIfInListOrThrowStandardExceptionOrCause(ImmutableSet.<TypeToken<? extends Throwable>> of(),
new RuntimeException(e));
}
static class TestException extends Exception {
private static final long serialVersionUID = 1L;
}
}