JCLOUDS-1074: Guava 20 compatibility

* dynamically call TypeToken.isSupertypeOf with Guava 19 and later and
  TypeToken.isAssignableFrom with Guava 18 and earlier
* consume or ignore values from methods with CheckReturnValue
* replace usage of removed Iterators.emptyIterator
This commit is contained in:
Andrew Gaul 2016-02-04 14:36:21 -08:00
parent 7aad599721
commit 7cde28a4d2
13 changed files with 103 additions and 12 deletions

View File

@ -16,6 +16,7 @@
*/
package org.jclouds.docker.features;
import static org.assertj.guava.api.Assertions.assertThat;
import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertNotNull;
import static org.testng.Assert.assertNull;
@ -29,6 +30,7 @@ import org.jclouds.docker.domain.ImageSummary;
import org.jclouds.docker.options.CreateImageOptions;
import org.testng.annotations.Test;
import com.google.common.base.Optional;
import com.google.common.base.Predicate;
import com.google.common.collect.Iterables;
@ -61,12 +63,13 @@ public class ImageApiLiveTest extends BaseDockerApiLiveTest {
List<ImageSummary> listImages = api().listImages();
assertNotNull(listImages);
Iterables.find(listImages, new Predicate<ImageSummary>() {
Optional<ImageSummary> summary = Iterables.tryFind(listImages, new Predicate<ImageSummary>() {
@Override
public boolean apply(ImageSummary input) {
return input.repoTags().contains("jclouds:testTag");
}
});
assertThat(summary).isPresent();
}
@Test(dependsOnMethods = "testListImages", alwaysRun = true)

View File

@ -44,6 +44,7 @@ public class UpdateCDNContainerOptionsTest {
assertEquals(ImmutableList.of("123456"), options.buildRequestHeaders().get(CDN_TTL));
}
@SuppressWarnings("CheckReturnValue")
@Test(expectedExceptions = IllegalStateException.class)
public void testTTLLessThanMin() {
UpdateCDNContainerOptions options =
@ -51,6 +52,7 @@ public class UpdateCDNContainerOptionsTest {
options.buildRequestHeaders().get(CDN_TTL);
}
@SuppressWarnings("CheckReturnValue")
@Test(expectedExceptions = IllegalStateException.class)
public void testTTLGreaterThanMax() {
UpdateCDNContainerOptions options =

View File

@ -27,6 +27,7 @@ import org.jclouds.googlecloud.options.ListOptions;
import org.jclouds.javax.annotation.Nullable;
import com.google.common.collect.AbstractIterator;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.Iterators;
public final class ListPages {
@ -49,7 +50,7 @@ public final class ListPages {
}
static <T> Iterator<ListPage<T>> singletonOrEmptyIterator(ListPage<T> input) {
return input.isEmpty() ? Iterators.<ListPage<T>>emptyIterator() : Iterators.singletonIterator(input);
return input.isEmpty() ? ImmutableList.<ListPage<T>>of().iterator() : Iterators.singletonIterator(input);
}
private ListPages() {

View File

@ -82,6 +82,7 @@ import org.jclouds.rest.config.CredentialStoreModule;
import org.jclouds.rest.config.HttpApiModule;
import org.jclouds.rest.config.RestModule;
import org.jclouds.rest.internal.InvokeHttpMethod;
import org.jclouds.util.TypeTokenUtils;
import com.google.common.annotations.VisibleForTesting;
import com.google.common.base.Function;
@ -620,7 +621,7 @@ public class ContextBuilder {
@SuppressWarnings("unchecked")
public <C extends Context> C build(TypeToken<C> contextType) {
TypeToken<C> returnType = null;
if (contextType.isAssignableFrom(apiMetadata.getContext()))
if (TypeTokenUtils.isSupertypeOf(contextType, apiMetadata.getContext()))
returnType = (TypeToken<C>) apiMetadata.getContext();
else
throw new IllegalArgumentException(String.format("api %s not assignable from %s; context: %s", apiMetadata,

View File

@ -20,6 +20,7 @@ import static com.google.common.base.Preconditions.checkNotNull;
import static com.google.common.base.Strings.emptyToNull;
import org.jclouds.View;
import org.jclouds.util.TypeTokenUtils;
import com.google.common.base.Predicate;
import com.google.common.base.Predicates;
@ -84,7 +85,7 @@ public class ApiPredicates {
*/
@Override
public boolean apply(ApiMetadata apiMetadata) {
return type.isAssignableFrom(apiMetadata.getContext());
return TypeTokenUtils.isSupertypeOf(type, apiMetadata.getContext());
}
/**
@ -114,7 +115,7 @@ public class ApiPredicates {
@Override
public boolean apply(ApiMetadata apiMetadata) {
for (TypeToken<? extends View> to : apiMetadata.getViews())
if (type.isAssignableFrom(to))
if (TypeTokenUtils.isSupertypeOf(type, to))
return true;
return false;
}

View File

@ -26,6 +26,7 @@ import java.util.ServiceLoader;
import org.jclouds.View;
import org.jclouds.osgi.ApiRegistry;
import org.jclouds.util.TypeTokenUtils;
import com.google.common.base.Function;
import com.google.common.base.Predicate;
@ -131,7 +132,7 @@ public class Apis {
@Override
public boolean apply(TypeToken<?> input) {
return view.isAssignableFrom(input);
return TypeTokenUtils.isSupertypeOf(view, input);
}
});

View File

@ -25,6 +25,7 @@ import org.jclouds.Context;
import org.jclouds.View;
import org.jclouds.location.Provider;
import org.jclouds.rest.ApiContext;
import org.jclouds.util.TypeTokenUtils;
import com.google.common.base.Objects;
import com.google.common.base.Objects.ToStringHelper;
@ -45,7 +46,7 @@ public abstract class BaseView extends ForwardingObject implements View {
@SuppressWarnings("unchecked")
@Override
public <C extends Context> C unwrap(TypeToken<C> type) {
checkArgument(checkNotNull(type, "type").isAssignableFrom(backendType), "backend type: %s not assignable to %s", backendType, type);
checkArgument(TypeTokenUtils.isSupertypeOf(checkNotNull(type, "type"), backendType), "%s is not a supertype of backend type %s", type, backendType);
return (C) backend;
}

View File

@ -23,6 +23,7 @@ import org.jclouds.Context;
import org.jclouds.View;
import org.jclouds.apis.ApiMetadata;
import org.jclouds.apis.ApiPredicates;
import org.jclouds.util.TypeTokenUtils;
import com.google.common.base.Preconditions;
import com.google.common.base.Predicate;
@ -237,7 +238,7 @@ public class ProviderPredicates {
*/
@Override
public boolean apply(ProviderMetadata providerMetadata) {
return apiClass.isAssignableFrom(providerMetadata.getApiMetadata().getClass());
return TypeTokenUtils.isSupertypeOf(apiClass, providerMetadata.getApiMetadata().getClass());
}
/**

View File

@ -129,7 +129,7 @@ public class InputParamValidator {
}
}
@SuppressWarnings("unchecked")
@SuppressWarnings({"CheckReturnValue", "unchecked"})
private void runPredicatesAgainstArgs(List<Validator<?>> predicates, List<Object> args) {
for (@SuppressWarnings("rawtypes")
Validator validator : predicates) {

View File

@ -0,0 +1,74 @@
/*
* 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.Method;
import java.lang.reflect.Type;
import com.google.common.annotations.Beta;
import com.google.common.base.Throwables;
import com.google.common.reflect.TypeToken;
@Beta
public final class TypeTokenUtils {
private static final Method IS_SUPERTYPE_OF_TYPE;
private static final Method IS_SUPERTYPE_OF_TYPETOKEN;
static {
Method isSuperTypeOfType;
Method isSuperTypeOfTypeToken;
try {
// Guava 19 and later method
isSuperTypeOfType = TypeToken.class.getDeclaredMethod("isSupertypeOf", Type.class);
isSuperTypeOfTypeToken = TypeToken.class.getDeclaredMethod("isSupertypeOf", TypeToken.class);
} catch (NoSuchMethodException nsme) {
try {
// Guava 18 and earlier method
isSuperTypeOfType = TypeToken.class.getDeclaredMethod("isAssignableFrom", Type.class);
isSuperTypeOfTypeToken = TypeToken.class.getDeclaredMethod("isAssignableFrom", TypeToken.class);
} catch (NoSuchMethodException nsme2) {
throw Throwables.propagate(nsme2);
}
}
IS_SUPERTYPE_OF_TYPE = isSuperTypeOfType;
IS_SUPERTYPE_OF_TYPETOKEN = isSuperTypeOfTypeToken;
}
private TypeTokenUtils() {
throw new AssertionError("intentionally not implemented");
}
public static <C> boolean isSupertypeOf(TypeToken<C> token, Type type) {
try {
return (Boolean) IS_SUPERTYPE_OF_TYPE.invoke(token, type);
} catch (IllegalAccessException iae) {
throw Throwables.propagate(iae);
} catch (InvocationTargetException ite) {
throw Throwables.propagate(ite);
}
}
public static <C, D> boolean isSupertypeOf(TypeToken<C> token, TypeToken<D> token2) {
try {
return (Boolean) IS_SUPERTYPE_OF_TYPETOKEN.invoke(token, token2);
} catch (IllegalAccessException iae) {
throw Throwables.propagate(iae);
} catch (InvocationTargetException ite) {
throw Throwables.propagate(ite);
}
}
}

View File

@ -104,7 +104,7 @@ public class BaseViewTest {
wine.unwrap(typeToken(PeanutButter.class));
fail();
} catch (IllegalArgumentException e) {
assertEquals(e.getMessage(), "backend type: org.jclouds.internal.BaseViewTest$Water not assignable to org.jclouds.internal.BaseViewTest$PeanutButter");
assertEquals(e.getMessage(), "org.jclouds.internal.BaseViewTest$PeanutButter is not a supertype of backend type org.jclouds.internal.BaseViewTest$Water");
}
}

View File

@ -165,6 +165,7 @@ public class PlacementGroupApiLiveTest extends BaseComputeServiceContextLiveTest
assert availableTester.apply(group) : group;
}
@SuppressWarnings("CheckReturnValue")
public void testStartHS1Instance() throws Exception {
Template template = view.getComputeService().templateBuilder()

View File

@ -17,6 +17,7 @@
package org.jclouds.softlayer.features;
import static com.google.common.base.Preconditions.checkState;
import static org.assertj.core.api.Assertions.assertThat;
import static org.jclouds.util.Predicates2.retry;
import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertNotNull;
@ -132,9 +133,13 @@ public class VirtualGuestApiLiveTest extends BaseSoftLayerApiLiveTest {
VirtualGuest found = virtualGuestApi.getVirtualGuest(virtualGuest.getId());
Set<TagReference> tagReferences = found.getTagReferences();
assertNotNull(tagReferences);
for (String tag : tags) {
Iterables.contains(tagReferences, tag);
ImmutableSet.Builder<String> actualTagsBuilder = ImmutableSet.builder();
for (TagReference ref : tagReferences) {
actualTagsBuilder.add(ref.getTag().getName());
}
Set<String> actualTags = actualTagsBuilder.build();
assertThat(actualTags).containsAll(tags);
}
@Test(dependsOnMethods = "testSetTagsOnVirtualGuest")