Updated Branches: refs/heads/JCLOUDS-427 4ae4aae99 -> 3d28bddee
Moving the temporary TypeToken2 into org.jclouds.util (see 384571040) Makes the code more complicated and expensive, though, since we now need reflection to get at package-private things. Project: http://git-wip-us.apache.org/repos/asf/jclouds/repo Commit: http://git-wip-us.apache.org/repos/asf/jclouds/commit/3d28bdde Tree: http://git-wip-us.apache.org/repos/asf/jclouds/tree/3d28bdde Diff: http://git-wip-us.apache.org/repos/asf/jclouds/diff/3d28bdde Branch: refs/heads/JCLOUDS-427 Commit: 3d28bddeef087bffa23252ac8abc50065f16d1dc Parents: 4ae4aae Author: Andrew Phillips <[email protected]> Authored: Thu Jan 23 11:41:02 2014 -0500 Committer: Andrew Phillips <[email protected]> Committed: Thu Jan 23 11:41:02 2014 -0500 ---------------------------------------------------------------------- .../com/google/common/reflect/TypeToken2.java | 44 ----------- .../org/jclouds/rest/config/BinderUtils.java | 15 ++-- .../rest/internal/BaseRestApiMetadata.java | 8 +- .../main/java/org/jclouds/util/TypeToken2.java | 78 ++++++++++++++++++++ 4 files changed, 90 insertions(+), 55 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/jclouds/blob/3d28bdde/core/src/main/java/com/google/common/reflect/TypeToken2.java ---------------------------------------------------------------------- diff --git a/core/src/main/java/com/google/common/reflect/TypeToken2.java b/core/src/main/java/com/google/common/reflect/TypeToken2.java deleted file mode 100644 index 1ca4752..0000000 --- a/core/src/main/java/com/google/common/reflect/TypeToken2.java +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF 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 com.google.common.reflect; - -import com.google.common.collect.ImmutableMap; -import com.google.common.reflect.TypeParameter; -import com.google.common.reflect.TypeToken; - -/* - * FIXME: remove this class ASAP! - * - * Evil stuff, adapted from https://code.google.com/p/guava-libraries/source/browse/guava/src/com/google/common/reflect/TypeToken.java#236. - * See https://issues.apache.org/jira/browse/JCLOUDS-427 and - * https://code.google.com/p/guava-libraries/issues/detail?id=1635 - */ -public class TypeToken2<T> extends TypeToken<T> { - @SuppressWarnings("unchecked") - public <X, Y> TypeToken<T> where(TypeParameter<X> typeParam1, - TypeToken<X> typeArg1, TypeParameter<Y> typeParam2, TypeToken<Y> typeArg2) { - // resolving both parameters in one shot seems to work around 1635 - TypeResolver resolver = new TypeResolver() - .where(ImmutableMap.of(typeParam1.typeVariable, typeArg1.getType(), typeParam2.typeVariable, typeArg2.getType())); - return (TypeToken<T>) TypeToken.of(resolver.resolveType(getType())); - } - - public <X, Y> TypeToken<T> where(TypeParameter<X> typeParam1, Class<X> typeArg1, - TypeParameter<Y> typeParam2, Class<Y> typeArg2) { - return where(typeParam1, of(typeArg1), typeParam2, of(typeArg2)); - } -} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/jclouds/blob/3d28bdde/core/src/main/java/org/jclouds/rest/config/BinderUtils.java ---------------------------------------------------------------------- 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 8d3fdbe..6a79d5e 100644 --- a/core/src/main/java/org/jclouds/rest/config/BinderUtils.java +++ b/core/src/main/java/org/jclouds/rest/config/BinderUtils.java @@ -18,10 +18,11 @@ package org.jclouds.rest.config; import com.google.common.reflect.TypeParameter; import com.google.common.reflect.TypeToken; -import com.google.common.reflect.TypeToken2; import com.google.inject.Binder; import com.google.inject.TypeLiteral; -import java.util.Map; + +import org.jclouds.util.TypeToken2; +import org.jclouds.util.TypeToken2.TypeParameter2; /** * @@ -102,12 +103,12 @@ public class BinderUtils { @SuppressWarnings({ "unchecked", "serial" }) private static <S, A> void bindHttpApiProvider(Binder binder, Class<S> sync, Class<A> async) { TypeToken<SyncToAsyncHttpApiProvider<S, A>> token = new TypeToken2<SyncToAsyncHttpApiProvider<S, A>>() { - }.where(new TypeParameter<S>() { - }, sync, new TypeParameter<A>() { + }.where(new TypeParameter2<S>() { + }, sync, new TypeParameter2<A>() { }, async); binder.bind(sync).toProvider(TypeLiteral.class.cast(TypeLiteral.get(token.getType()))); } - + /** * adds an explicit binding for an interface which synchronously blocks on * similar calls to an {@code async} type. @@ -142,8 +143,8 @@ public class BinderUtils { @SuppressWarnings({ "unchecked", "serial" }) private static <S, A> void bindCallGetOnFutures(Binder binder, Class<S> sync, Class<A> async) { TypeToken<CallGetOnFuturesProvider<S, A>> token = new TypeToken2<CallGetOnFuturesProvider<S, A>>() { - }.where(new TypeParameter<S>() { - }, sync, new TypeParameter<A>() { + }.where(new TypeParameter2<S>() { + }, sync, new TypeParameter2<A>() { }, async); binder.bind(sync).toProvider(TypeLiteral.class.cast(TypeLiteral.get(token.getType()))); } http://git-wip-us.apache.org/repos/asf/jclouds/blob/3d28bdde/core/src/main/java/org/jclouds/rest/internal/BaseRestApiMetadata.java ---------------------------------------------------------------------- diff --git a/core/src/main/java/org/jclouds/rest/internal/BaseRestApiMetadata.java b/core/src/main/java/org/jclouds/rest/internal/BaseRestApiMetadata.java index 800ce4f..8af312d 100644 --- a/core/src/main/java/org/jclouds/rest/internal/BaseRestApiMetadata.java +++ b/core/src/main/java/org/jclouds/rest/internal/BaseRestApiMetadata.java @@ -24,12 +24,12 @@ import java.util.Properties; import org.jclouds.apis.ApiMetadata; import org.jclouds.apis.internal.BaseApiMetadata; import org.jclouds.rest.RestApiMetadata; +import org.jclouds.util.TypeToken2; +import org.jclouds.util.TypeToken2.TypeParameter2; import com.google.common.annotations.Beta; import com.google.common.base.Objects.ToStringHelper; -import com.google.common.reflect.TypeParameter; import com.google.common.reflect.TypeToken; -import com.google.common.reflect.TypeToken2; /** * Useful in creating rest apis. @@ -59,8 +59,8 @@ public abstract class BaseRestApiMetadata extends BaseApiMetadata implements Res public static <S, A> TypeToken<org.jclouds.rest.RestContext<S, A>> contextToken(TypeToken<S> apiToken, TypeToken<A> asyncApiToken) { return new TypeToken2<org.jclouds.rest.RestContext<S, A>>() { private static final long serialVersionUID = 1L; - }.where(new TypeParameter<S>() { - }, apiToken, new TypeParameter<A>() { + }.where(new TypeParameter2<S>() { + }, apiToken, new TypeParameter2<A>() { }, asyncApiToken); } http://git-wip-us.apache.org/repos/asf/jclouds/blob/3d28bdde/core/src/main/java/org/jclouds/util/TypeToken2.java ---------------------------------------------------------------------- diff --git a/core/src/main/java/org/jclouds/util/TypeToken2.java b/core/src/main/java/org/jclouds/util/TypeToken2.java new file mode 100644 index 0000000..b244aed --- /dev/null +++ b/core/src/main/java/org/jclouds/util/TypeToken2.java @@ -0,0 +1,78 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF 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.util; + +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.ParameterizedType; +import java.lang.reflect.Type; +import java.lang.reflect.TypeVariable; +import java.util.Map; + +import org.jclouds.reflect.Reflection2; + +import com.google.common.collect.ImmutableMap; +import com.google.common.reflect.Invokable; +import com.google.common.reflect.TypeParameter; +import com.google.common.reflect.TypeResolver; +import com.google.common.reflect.TypeToken; + +/* + * FIXME: remove this class ASAP! + * + * Evil stuff, adapted from https://code.google.com/p/guava-libraries/source/browse/guava/src/com/google/common/reflect/TypeToken.java#236. + * See https://issues.apache.org/jira/browse/JCLOUDS-427 and + * https://code.google.com/p/guava-libraries/issues/detail?id=1635 + */ +public class TypeToken2<T> extends TypeToken<T> { + private static final long serialVersionUID = 1L; + + @SuppressWarnings("unchecked") + public <X, Y> TypeToken<T> where(TypeParameter2<X> typeParam1, + TypeToken<X> typeArg1, TypeParameter2<Y> typeParam2, TypeToken<Y> typeArg2) { + // resolving both parameters in one shot seems to work around 1635 + TypeResolver resolver = new TypeResolver(); + // where(Map...) is package-private in TypeResolver + Invokable<TypeResolver, TypeResolver> whereWithMap = + Reflection2.<TypeResolver, TypeResolver>method( + TypeResolver.class, "where", Map.class); + try { + resolver = whereWithMap.invoke(resolver, ImmutableMap.of( + typeParam1.getTypeVariable(), typeArg1.getType(), + typeParam2.getTypeVariable(), typeArg2.getType())); + } catch (IllegalAccessException exception) { + // should never happen + throw new IllegalStateException(exception); + } catch (InvocationTargetException exception) { + // should never happen + throw new IllegalStateException(exception); + } + return (TypeToken<T>) TypeToken.of(resolver.resolveType(getType())); + } + + public <X, Y> TypeToken<T> where(TypeParameter2<X> typeParam1, Class<X> typeArg1, + TypeParameter2<Y> typeParam2, Class<Y> typeArg2) { + return where(typeParam1, of(typeArg1), typeParam2, of(typeArg2)); + } + + public static abstract class TypeParameter2<T> extends TypeParameter<T> { + TypeVariable<?> getTypeVariable() { + // duplicated from TypeCapture, where it's package-private + Type superclass = getClass().getGenericSuperclass(); + return (TypeVariable<?>) ((ParameterizedType) superclass).getActualTypeArguments()[0]; + } + } +} \ No newline at end of file
