Updated Branches: refs/heads/master b3a320e01 -> 334bd3673
JCLOUDS-82: Added method to get the underlying Api from a View Project: http://git-wip-us.apache.org/repos/asf/incubator-jclouds/repo Commit: http://git-wip-us.apache.org/repos/asf/incubator-jclouds/commit/334bd367 Tree: http://git-wip-us.apache.org/repos/asf/incubator-jclouds/tree/334bd367 Diff: http://git-wip-us.apache.org/repos/asf/incubator-jclouds/diff/334bd367 Branch: refs/heads/master Commit: 334bd367302b058b0eef1444d05a6a43ecd3f065 Parents: b3a320e Author: Ignasi Barrera <[email protected]> Authored: Fri May 24 09:23:53 2013 +0200 Committer: Ignasi Barrera <[email protected]> Committed: Mon May 27 22:13:25 2013 +0200 ---------------------------------------------------------------------- core/src/main/java/org/jclouds/View.java | 12 ++++ .../main/java/org/jclouds/internal/BaseView.java | 15 ++++ .../java/org/jclouds/internal/BaseViewTest.java | 51 ++++++++++++++- 3 files changed, 77 insertions(+), 1 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/incubator-jclouds/blob/334bd367/core/src/main/java/org/jclouds/View.java ---------------------------------------------------------------------- diff --git a/core/src/main/java/org/jclouds/View.java b/core/src/main/java/org/jclouds/View.java index 30f8863..08ed544 100644 --- a/core/src/main/java/org/jclouds/View.java +++ b/core/src/main/java/org/jclouds/View.java @@ -16,6 +16,8 @@ */ package org.jclouds; +import java.io.Closeable; + import com.google.common.annotations.Beta; import com.google.common.reflect.TypeToken; @@ -68,4 +70,14 @@ public interface View { */ <C extends Context> C unwrap() throws ClassCastException; + /** + * Unwraps the underlying api from this view. + * + * @param apiClass The class of the api to unwrap. + * @return The unwrapped api. + * + * @since 1.7 + */ + <A extends Closeable> A unwrapApi(Class<A> apiClass); + } http://git-wip-us.apache.org/repos/asf/incubator-jclouds/blob/334bd367/core/src/main/java/org/jclouds/internal/BaseView.java ---------------------------------------------------------------------- diff --git a/core/src/main/java/org/jclouds/internal/BaseView.java b/core/src/main/java/org/jclouds/internal/BaseView.java index 38fbbfb..250f49f 100644 --- a/core/src/main/java/org/jclouds/internal/BaseView.java +++ b/core/src/main/java/org/jclouds/internal/BaseView.java @@ -19,15 +19,19 @@ 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 java.io.Closeable; + import javax.inject.Singleton; import org.jclouds.Context; import org.jclouds.View; import org.jclouds.location.Provider; +import org.jclouds.rest.ApiContext; import com.google.common.base.Objects; import com.google.common.base.Objects.ToStringHelper; import com.google.common.collect.ForwardingObject; +import com.google.common.reflect.TypeParameter; import com.google.common.reflect.TypeToken; /** @@ -63,6 +67,17 @@ public abstract class BaseView extends ForwardingObject implements View { } @Override + public <A extends Closeable> A unwrapApi(Class<A> apiClass) { + checkArgument(ApiContext.class.isAssignableFrom(backendType.getRawType()), + "backend type: %s should be an ApiContext", backendType); + TypeToken<ApiContext<A>> contextToken = new TypeToken<ApiContext<A>>(delegate().getClass()) { + private static final long serialVersionUID = 1L; + }.where(new TypeParameter<A>() { + }, TypeToken.of(apiClass)); + return unwrap(contextToken).getApi(); + } + + @Override protected Context delegate() { return backend; } http://git-wip-us.apache.org/repos/asf/incubator-jclouds/blob/334bd367/core/src/test/java/org/jclouds/internal/BaseViewTest.java ---------------------------------------------------------------------- diff --git a/core/src/test/java/org/jclouds/internal/BaseViewTest.java b/core/src/test/java/org/jclouds/internal/BaseViewTest.java index 4270fdd..2d82e3b 100644 --- a/core/src/test/java/org/jclouds/internal/BaseViewTest.java +++ b/core/src/test/java/org/jclouds/internal/BaseViewTest.java @@ -17,19 +17,27 @@ package org.jclouds.internal; import static org.easymock.EasyMock.createMock; +import static org.easymock.EasyMock.expect; +import static org.easymock.EasyMock.replay; +import static org.easymock.EasyMock.verify; import static org.jclouds.reflect.Reflection2.typeToken; import static org.testng.Assert.assertEquals; import static org.testng.Assert.assertNotEquals; import static org.testng.Assert.fail; +import java.io.Closeable; +import java.io.IOException; + import org.jclouds.domain.Credentials; import org.jclouds.lifecycle.Closer; import org.jclouds.providers.ProviderMetadata; +import org.jclouds.rest.ApiContext; import org.jclouds.rest.Utils; import org.testng.annotations.Test; import com.google.common.base.Supplier; import com.google.common.base.Suppliers; +import com.google.common.reflect.TypeToken; /** * @author Adrian Cole @@ -66,6 +74,23 @@ public class BaseViewTest { } } + private static class DummyApi implements Closeable { + + @Override + public void close() throws IOException { + + } + } + + public class DummyView extends BaseView { + + protected DummyView(ApiContext<DummyApi> context) { + super(context, new TypeToken<ApiContext<DummyApi>>() { + private static final long serialVersionUID = 1L; + }); + } + } + public void testWaterTurnedIntoWine() { Wine wine = new Wine(); assertEquals(wine.getBackendType(), typeToken(Water.class)); @@ -83,5 +108,29 @@ public class BaseViewTest { assertEquals(e.getMessage(), "backend type: org.jclouds.internal.BaseViewTest$Water not assignable from org.jclouds.internal.BaseViewTest$PeanutButter"); } } - + + public void testCannotUnwrapIfNotApiContext() { + Wine wine = new Wine(); + try { + wine.unwrapApi(DummyApi.class); + fail(); + } catch (IllegalArgumentException e) { + assertEquals(e.getMessage(), "backend type: org.jclouds.internal.BaseViewTest$Water should be an ApiContext"); + } + } + + @SuppressWarnings("unchecked") + public void testUnwrapApi() { + DummyApi beer = new DummyApi(); + ApiContext<DummyApi> beerContext = createMock(ApiContext.class); + expect(beerContext.getApi()).andReturn(beer); + replay(beerContext); + + DummyView bar = new DummyView(beerContext); + DummyApi result = bar.unwrapApi(DummyApi.class); + + assertEquals(result, beer); + verify(beerContext); + } + }
