From c30fedec20f2d90fc0b89f5e8bb28dd0b6323c9b Mon Sep 17 00:00:00 2001 From: Adrian Cole Date: Sun, 2 Dec 2012 12:27:57 -0800 Subject: [PATCH] updated to employ Reflection.newProxy + AbstractInvocationHandler --- ...paceEqualsAnyNamespaceInExtensionsSet.java | 4 +- .../internal/CallerArg0ToPagedIterable.java | 2 +- .../concurrent/internal/SyncProxy.java | 39 ++++--------------- .../org/jclouds/internal/ClassMethodArgs.java | 12 +++--- .../internal/ClassMethodArgsAndReturnVal.java | 4 +- .../org/jclouds/rest/AsyncClientFactory.java | 13 +++---- .../org/jclouds/rest/config/BinderUtils.java | 11 ------ .../org/jclouds/rest/config/RestModule.java | 7 ++-- .../rest/internal/AsyncRestClientProxy.java | 33 +++------------- 9 files changed, 31 insertions(+), 94 deletions(-) diff --git a/apis/openstack-keystone/src/main/java/org/jclouds/openstack/v2_0/functions/PresentWhenExtensionAnnotationNamespaceEqualsAnyNamespaceInExtensionsSet.java b/apis/openstack-keystone/src/main/java/org/jclouds/openstack/v2_0/functions/PresentWhenExtensionAnnotationNamespaceEqualsAnyNamespaceInExtensionsSet.java index a08a451c19..0288c98297 100644 --- a/apis/openstack-keystone/src/main/java/org/jclouds/openstack/v2_0/functions/PresentWhenExtensionAnnotationNamespaceEqualsAnyNamespaceInExtensionsSet.java +++ b/apis/openstack-keystone/src/main/java/org/jclouds/openstack/v2_0/functions/PresentWhenExtensionAnnotationNamespaceEqualsAnyNamespaceInExtensionsSet.java @@ -62,11 +62,11 @@ public class PresentWhenExtensionAnnotationNamespaceEqualsAnyNamespaceInExtensio org.jclouds.openstack.v2_0.services.Extension.class)); if (ext.isPresent()) { URI namespace = URI.create(ext.get().namespace()); - if (input.getArgs() == null || input.getArgs().length == 0) { + if (input.getArgs().length == 0) { if (Iterables.any(extensions.getUnchecked(""), ExtensionPredicates.namespaceOrAliasEquals(namespace, aliases.get(namespace)))) return Optional.of(input.getReturnVal()); - } else if (input.getArgs() != null && input.getArgs().length == 1) { + } else if (input.getArgs().length == 1) { if (Iterables.any(extensions.getUnchecked(checkNotNull(input.getArgs()[0], "arg[0] in %s", input).toString()), ExtensionPredicates.namespaceOrAliasEquals(namespace, aliases.get(namespace)))) return Optional.of(input.getReturnVal()); diff --git a/core/src/main/java/org/jclouds/collect/internal/CallerArg0ToPagedIterable.java b/core/src/main/java/org/jclouds/collect/internal/CallerArg0ToPagedIterable.java index a1ddedb14b..c1f5e16803 100644 --- a/core/src/main/java/org/jclouds/collect/internal/CallerArg0ToPagedIterable.java +++ b/core/src/main/java/org/jclouds/collect/internal/CallerArg0ToPagedIterable.java @@ -63,7 +63,7 @@ public abstract class CallerArg0ToPagedIterable arg0Option = Optional.absent(); - if (request.getCaller().get().getArgs() != null && request.getCaller().get().getArgs().length > 0) { + if (request.getCaller().get().getArgs().length > 0) { Object arg0 = request.getCaller().get().getArgs()[0]; if (arg0 != null) arg0Option = Optional.of(arg0.toString()); diff --git a/core/src/main/java/org/jclouds/concurrent/internal/SyncProxy.java b/core/src/main/java/org/jclouds/concurrent/internal/SyncProxy.java index bcbb50ee16..d6078901e5 100644 --- a/core/src/main/java/org/jclouds/concurrent/internal/SyncProxy.java +++ b/core/src/main/java/org/jclouds/concurrent/internal/SyncProxy.java @@ -19,11 +19,10 @@ package org.jclouds.concurrent.internal; import static com.google.common.base.Preconditions.checkState; +import static com.google.common.reflect.Reflection.newProxy; -import java.lang.reflect.InvocationHandler; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; -import java.lang.reflect.Proxy; import java.util.Arrays; import java.util.Map; import java.util.Set; @@ -46,6 +45,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.util.concurrent.ListenableFuture; import com.google.inject.ProvisionException; @@ -54,15 +54,13 @@ import com.google.inject.ProvisionException; * * @author Adrian Cole */ -public class SyncProxy implements InvocationHandler { +public class SyncProxy extends AbstractInvocationHandler { - @SuppressWarnings("unchecked") public static T proxy(Function> optionalConverter, Class clazz, Object async, @Named("sync") LoadingCache delegateMap, Map, Class> sync2Async, Map timeouts) throws IllegalArgumentException, SecurityException, NoSuchMethodException { - return (T) Proxy.newProxyInstance(clazz.getClassLoader(), new Class[] { clazz }, - new SyncProxy(optionalConverter, clazz, async, delegateMap, sync2Async, timeouts)); + return newProxy(clazz, new SyncProxy(optionalConverter, clazz, async, delegateMap, sync2Async, timeouts)); } private final Function> optionalConverter; @@ -134,14 +132,9 @@ public class SyncProxy implements InvocationHandler { return methodNanos; } - public Object invoke(Object o, Method method, Object[] args) throws Exception { - if (method.getName().equals("equals")) { - return this.equals(o); - } else if (method.getName().equals("hashCode")) { - return this.hashCode(); - } else if (method.getName().equals("toString")) { - return this.toString(); - } else if (method.isAnnotationPresent(Delegate.class)) { + @Override + protected Object handleInvocation(Object o, Method method, Object[] args) throws Exception { + if (method.isAnnotationPresent(Delegate.class)) { Class syncClass = Optionals2.returnTypeOrTypeOfOptional(method); // get the return type of the asynchronous class associated with this client // ex. FloatingIPClient is associated with FloatingIPAsyncClient @@ -191,24 +184,8 @@ public class SyncProxy implements InvocationHandler { } return timeout != null ? TimeUnit.MILLISECONDS.toNanos(timeout) : null; } - + @Override - public boolean equals(Object obj) { - if (obj == null || !(obj instanceof SyncProxy)) - return false; - SyncProxy other = (SyncProxy) obj; - if (other == this) - return true; - if (other.declaring != this.declaring) - return false; - return super.equals(obj); - } - - @Override - public int hashCode() { - return declaring.hashCode(); - } - public String toString() { return "Sync Proxy for: " + delegate.getClass().getSimpleName(); } diff --git a/core/src/main/java/org/jclouds/internal/ClassMethodArgs.java b/core/src/main/java/org/jclouds/internal/ClassMethodArgs.java index 8a84a0da53..086928a888 100644 --- a/core/src/main/java/org/jclouds/internal/ClassMethodArgs.java +++ b/core/src/main/java/org/jclouds/internal/ClassMethodArgs.java @@ -24,8 +24,6 @@ import static com.google.common.base.Preconditions.checkNotNull; import java.lang.reflect.Method; import java.util.Arrays; -import org.jclouds.javax.annotation.Nullable; - import com.google.common.base.Objects; import com.google.common.base.Objects.ToStringHelper; @@ -48,7 +46,7 @@ public class ClassMethodArgs { public abstract static class Builder> { private Class clazz; private Method method; - private Object[] args; + private Object[] args = {}; @SuppressWarnings("unchecked") protected B self() { @@ -96,10 +94,10 @@ public class ClassMethodArgs { this(builder.clazz, builder.method, builder.args); } - public ClassMethodArgs(Class clazz, Method method, @Nullable Object[] args) { + public ClassMethodArgs(Class clazz, Method method, Object[] args) { this.clazz = checkNotNull(clazz, "clazz"); this.method = checkNotNull(method, "method"); - this.args = args; + this.args = checkNotNull(args, "args"); } public Class getClazz() { @@ -110,7 +108,7 @@ public class ClassMethodArgs { return method; } - @Nullable public Object[] getArgs() { + public Object[] getArgs() { return args; } @@ -136,6 +134,6 @@ public class ClassMethodArgs { protected ToStringHelper string() { return Objects.toStringHelper("").omitNullValues().add("clazz", clazz).add("method", method) - .add("args", args != null ? Arrays.asList(args) : null); + .add("args", args.length != 0 ? Arrays.asList(args) : null); } } diff --git a/core/src/main/java/org/jclouds/internal/ClassMethodArgsAndReturnVal.java b/core/src/main/java/org/jclouds/internal/ClassMethodArgsAndReturnVal.java index aa881cb4cd..909d57fe0f 100644 --- a/core/src/main/java/org/jclouds/internal/ClassMethodArgsAndReturnVal.java +++ b/core/src/main/java/org/jclouds/internal/ClassMethodArgsAndReturnVal.java @@ -22,8 +22,6 @@ import static com.google.common.base.Objects.equal; import java.lang.reflect.Method; -import org.jclouds.javax.annotation.Nullable; - import com.google.common.base.Objects; import com.google.common.base.Objects.ToStringHelper; @@ -68,7 +66,7 @@ public class ClassMethodArgsAndReturnVal extends ClassMethodArgs { private final Object returnVal; - public ClassMethodArgsAndReturnVal(Class clazz, Method method, @Nullable Object[] args, Object returnVal) { + public ClassMethodArgsAndReturnVal(Class clazz, Method method, Object[] args, Object returnVal) { super(clazz, method, args); this.returnVal = returnVal; } diff --git a/core/src/main/java/org/jclouds/rest/AsyncClientFactory.java b/core/src/main/java/org/jclouds/rest/AsyncClientFactory.java index 6aa6e430aa..c28a03b0d3 100644 --- a/core/src/main/java/org/jclouds/rest/AsyncClientFactory.java +++ b/core/src/main/java/org/jclouds/rest/AsyncClientFactory.java @@ -18,7 +18,8 @@ */ package org.jclouds.rest; -import java.lang.reflect.Proxy; +import static com.google.common.reflect.Reflection.newProxy; +import static com.google.inject.util.Types.newParameterizedType; import javax.inject.Inject; import javax.inject.Singleton; @@ -28,7 +29,6 @@ import org.jclouds.rest.internal.AsyncRestClientProxy; import com.google.inject.Injector; import com.google.inject.Key; import com.google.inject.TypeLiteral; -import com.google.inject.util.Types; /** * @@ -45,12 +45,9 @@ public class AsyncClientFactory { @SuppressWarnings("unchecked") public T create(Class clazz) { - return (T) create(clazz, (AsyncRestClientProxy) injector.getInstance(Key.get(TypeLiteral - .get(Types.newParameterizedType(AsyncRestClientProxy.class, clazz))))); + Key> key = (Key>) Key.get(TypeLiteral.get(newParameterizedType( + AsyncRestClientProxy.class, clazz))); + return newProxy(clazz, injector.getInstance(key)); } - @SuppressWarnings("unchecked") - public static T create(Class clazz, AsyncRestClientProxy proxy) { - return (T) Proxy.newProxyInstance(clazz.getClassLoader(), new Class[] { clazz }, proxy); - } } diff --git a/core/src/main/java/org/jclouds/rest/config/BinderUtils.java b/core/src/main/java/org/jclouds/rest/config/BinderUtils.java index f65fef02a3..2cc1747d5f 100644 --- a/core/src/main/java/org/jclouds/rest/config/BinderUtils.java +++ b/core/src/main/java/org/jclouds/rest/config/BinderUtils.java @@ -94,15 +94,4 @@ public class BinderUtils { binder.bind(asyncClientType).toProvider(asyncProvider); } - @SuppressWarnings("unchecked") - public static T newNullProxy(Class clazz) { - return (T) Proxy.newProxyInstance(clazz.getClassLoader(), new Class[] { clazz }, new InvocationHandler() { - - @Override - public Object invoke(Object proxy, Method method, Object[] args) { - return null; - } - - }); - } } diff --git a/core/src/main/java/org/jclouds/rest/config/RestModule.java b/core/src/main/java/org/jclouds/rest/config/RestModule.java index 8b23e775ab..ee8836a8c9 100644 --- a/core/src/main/java/org/jclouds/rest/config/RestModule.java +++ b/core/src/main/java/org/jclouds/rest/config/RestModule.java @@ -18,6 +18,7 @@ */ package org.jclouds.rest.config; +import static com.google.common.reflect.Reflection.newProxy; import static org.jclouds.Constants.PROPERTY_TIMEOUTS_PREFIX; import java.lang.reflect.Method; @@ -40,7 +41,6 @@ import org.jclouds.internal.ClassMethodArgs; import org.jclouds.internal.FilterStringsBoundToInjectorByName; import org.jclouds.json.config.GsonModule; import org.jclouds.location.config.LocationModule; -import org.jclouds.rest.AsyncClientFactory; import org.jclouds.rest.AuthorizationException; import org.jclouds.rest.HttpAsyncClient; import org.jclouds.rest.HttpClient; @@ -178,15 +178,14 @@ public class RestModule extends AbstractModule { TypeLiteral typeLiteral = TypeLiteral.get(clazz); RestAnnotationProcessor util = (RestAnnotationProcessor) injector.getInstance(Key.get(TypeLiteral.get(Types .newParameterizedType(RestAnnotationProcessor.class, clazz)))); - // cannot use child injectors due to the super coarse guice lock on - // Singleton + // cannot use child injectors due to the super coarse guice lock on Singleton util.setCaller(from); LoadingCache delegateMap = injector.getInstance(Key.get( new TypeLiteral>() { }, Names.named("async"))); AsyncRestClientProxy proxy = new AsyncRestClientProxy(injector, factory, util, typeLiteral, delegateMap); injector.injectMembers(proxy); - return AsyncClientFactory.create(clazz, proxy); + return newProxy(clazz, proxy); } } diff --git a/core/src/main/java/org/jclouds/rest/internal/AsyncRestClientProxy.java b/core/src/main/java/org/jclouds/rest/internal/AsyncRestClientProxy.java index 451c66d841..1729921e87 100644 --- a/core/src/main/java/org/jclouds/rest/internal/AsyncRestClientProxy.java +++ b/core/src/main/java/org/jclouds/rest/internal/AsyncRestClientProxy.java @@ -19,7 +19,6 @@ package org.jclouds.rest.internal; import java.lang.annotation.Annotation; -import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Type; import java.util.concurrent.ExecutionException; @@ -28,6 +27,7 @@ import javax.annotation.Resource; import javax.inject.Named; import javax.inject.Qualifier; import javax.inject.Singleton; +import javax.ws.rs.Path; import org.jclouds.Constants; import org.jclouds.concurrent.ExceptionParsingListenableFuture; @@ -51,6 +51,7 @@ import com.google.common.base.Throwables; import com.google.common.cache.LoadingCache; import com.google.common.collect.ImmutableList; import com.google.common.collect.Iterables; +import com.google.common.reflect.AbstractInvocationHandler; import com.google.common.util.concurrent.Futures; import com.google.common.util.concurrent.ListenableFuture; import com.google.inject.Binding; @@ -88,7 +89,7 @@ import com.google.inject.util.Types; * @author Adrian Cole */ @Singleton -public class AsyncRestClientProxy implements InvocationHandler { +public class AsyncRestClientProxy extends AbstractInvocationHandler { public Class getDeclaring() { return declaring; } @@ -133,14 +134,9 @@ public class AsyncRestClientProxy implements InvocationHandler { }; - public Object invoke(Object o, Method method, Object[] args) throws ExecutionException { - if (method.getName().equals("equals")) { - return this.equals(o); - } else if (method.getName().equals("toString")) { - return this.toString(); - } else if (method.getName().equals("hashCode")) { - return this.hashCode(); - } else if (method.isAnnotationPresent(Provides.class)) { + @Override + protected Object handleInvocation(Object proxy, Method method, Object[] args) throws ExecutionException { + if (method.isAnnotationPresent(Provides.class)) { return lookupValueFromGuice(method); } else if (method.isAnnotationPresent(Delegate.class)) { return propagateContextToDelegate(method, args); @@ -279,23 +275,6 @@ public class AsyncRestClientProxy implements InvocationHandler { public TransformingHttpCommand create(HttpRequest request, Function transformer); } - @Override - public boolean equals(Object obj) { - if (obj == null || !(obj instanceof AsyncRestClientProxy)) - return false; - AsyncRestClientProxy other = (AsyncRestClientProxy) obj; - if (other == this) - return true; - if (other.declaring != this.declaring) - return false; - return super.equals(obj); - } - - @Override - public int hashCode() { - return declaring.hashCode(); - } - public String toString() { return "Client Proxy for :" + declaring.getName(); }