From 5b7878b0ea1f876b4b28c49cb19ed7e2d48fbd18 Mon Sep 17 00:00:00 2001 From: "adrian.f.cole" Date: Sat, 10 Oct 2009 00:18:34 +0000 Subject: [PATCH] Issue 76: added support for @Produces and @Consumes, replaced @EntityBinder with @DecoratorParam so that we can manipulate more things then just entities; organized rest module git-svn-id: http://jclouds.googlecode.com/svn/trunk@1952 3d8758e0-26b5-11de-8745-db77d3ebf521 --- .../java/org/jclouds/aws/s3/S3BlobStore.java | 26 +- .../java/org/jclouds/aws/s3/S3Connection.java | 39 +- .../AddACLAsXMLEntity.java} | 9 +- .../AddS3ObjectEntity.java} | 17 +- .../aws/s3/domain/ListBucketResponse.java | 2 +- .../s3/domain/TreeSetListBucketResponse.java | 2 +- .../storage/blob/AzureBlobConnection.java | 30 +- .../azure/storage/blob/AzureBlobStore.java | 24 +- .../azure/storage/blob/AzureBlobUtil.java | 12 +- .../AddBlobEntity.java} | 16 +- .../GenerateMD5AndAddBlobEntity.java} | 12 +- .../ParseContainerMetadataFromHeaders.java | 4 +- .../storage/blob/AzureBlobConnectionTest.java | 19 +- .../storage/blob/AzureBlobStoreTest.java | 10 +- .../storage/domain/BoundedSortedSet.java | 2 +- .../azure/storage/domain/BoundedTreeSet.java | 2 +- .../SharedKeyAuthenticationLiveTest.java | 10 +- .../storage/queue/AzureQueueConnection.java | 12 +- .../queue/AzureQueueConnectionTest.java | 10 +- .../AddBlobEntity.java} | 14 +- .../AddBlobEntityAsMultipartForm.java | 18 +- .../AddHeadersWithPrefix.java} | 11 +- .../org/jclouds/blobstore/domain}/Key.java | 2 +- .../functions/ClearAndDeleteIfNotEmpty.java | 4 +- .../ParseBlobFromHeadersAndHttpContent.java | 4 +- .../ParseContentTypeFromHeaders.java | 4 +- .../blobstore/internal/BaseBlobMap.java | 2 +- .../blobstore/util/BlobStoreUtils.java | 12 + .../AddBlobEntityAsMultipartFormTest.java | 24 +- .../blobstore/util/BlobStoreUtilsTest.java | 28 ++ .../jclouds/cloud/CloudContextBuilder.java | 4 +- .../functions/ParseContentMD5FromHeaders.java | 4 +- .../BaseHttpCommandExecutorService.java | 2 +- ...estContext.java => InvocationContext.java} | 2 +- .../org/jclouds/rest/RestClientFactory.java | 2 + .../DecoratorParam.java} | 12 +- .../rest/{ => annotations}/Endpoint.java | 2 +- .../{ => annotations}/ExceptionParser.java | 2 +- .../rest/{ => annotations}/Headers.java | 2 +- .../{ => annotations}/HostPrefixParam.java | 2 +- .../rest/{ => annotations}/MapBinder.java | 8 +- .../{ => annotations}/MapEntityParam.java | 4 +- .../rest/annotations/MatrixParams.java | 50 +++ .../rest/{ => annotations}/ParamParser.java | 2 +- .../rest/{ => annotations}/QueryParams.java | 2 +- .../{ => annotations}/RequestFilters.java | 2 +- .../{ => annotations}/ResponseParser.java | 2 +- .../rest/{ => annotations}/SkipEncoding.java | 2 +- .../rest/{ => annotations}/VirtualHost.java | 2 +- .../{ => annotations}/XMLResponseParser.java | 2 +- .../binders/HttpRequestOptionsBinder.java | 49 --- .../{JaxrsModule.java => RestModule.java} | 4 +- .../AddAsJsonEntity.java} | 11 +- .../AddAsStringEntity.java} | 13 +- .../MapRequestDecorator.java} | 8 +- .../RequestDecorator.java} | 6 +- .../rest/{ => internal}/BoundedSortedSet.java | 2 +- .../rest/{ => internal}/BoundedTreeSet.java | 2 +- .../RestAnnotationProcessor.java} | 380 ++++++++++++------ .../rest/{ => internal}/RestClientProxy.java | 15 +- .../{ => internal}/RuntimeDelegateImpl.java | 2 +- .../java/org/jclouds/http/BaseJettyTest.java | 2 +- .../jclouds/http/IntegrationTestClient.java | 25 +- ....java => RestAnnotationProcessorTest.java} | 371 ++++++++++++++--- .../pool/NioHttpCommandExecutionHandler.java | 2 +- .../org/jclouds/mezeo/pcs2/PCSBlobStore.java | 28 +- .../java/org/jclouds/mezeo/pcs2/PCSCloud.java | 6 +- .../org/jclouds/mezeo/pcs2/PCSConnection.java | 32 +- .../java/org/jclouds/mezeo/pcs2/PCSUtil.java | 13 +- .../mezeo/pcs2/config/PCSContextModule.java | 2 +- .../AddContainerNameAsXmlEntity.java} | 9 +- .../AddDataAndLength.java} | 9 +- .../AddFileInfoAsXmlEntity.java} | 15 +- .../pcs2/functions/AddEntryIntoMultiMap.java | 4 +- ...ddMetadataAndParseResourceIdIntoBytes.java | 5 +- ...sembleBlobFromContentAndMetadataCache.java | 5 +- .../ContainerAndFileNameToResourceId.java | 1 + ...eSubFolderIfNotExistsAndGetResourceId.java | 10 +- ...ubFolderIfNotExistsAndNewFileResource.java | 1 + .../pcs2/functions/FindIdInFileList.java | 5 +- ...eContainerNameCacheAndReturnTrueIf2xx.java | 4 +- ...validatePCSKeyCacheAndReturnVoidIf2xx.java | 5 +- .../org/jclouds/mezeo/pcs2/util/PCSUtils.java | 12 - .../jclouds/mezeo/pcs2/PCSBlobStoreTest.java | 46 +-- .../jclouds/mezeo/pcs2/PCSCloudLiveTest.java | 4 +- .../jclouds/mezeo/pcs2/PCSConnectionTest.java | 38 +- .../AddContainerNameAsXmlEntityTest.java} | 12 +- .../AddFileInfoAsXmlEntityTest.java} | 19 +- ...tadataAndParseResourceIdIntoBytesTest.java | 3 +- .../AssembleBlobFromBlobMetadataCallTest.java | 1 + .../jclouds/mezeo/pcs2/util/PCSUtilsTest.java | 14 - .../cloudfiles/CloudFilesBlobStore.java | 20 +- .../cloudfiles/CloudFilesConnection.java | 26 +- .../AddCFObjectEntity.java} | 17 +- .../cloudservers/CloudServersConnection.java | 56 +-- .../AddAdminPassAsJsonEntity.java} | 14 +- .../AddBackupScheduleAsJsonEntity.java} | 12 +- .../AddConfirmResizeAsJsonEntity.java} | 9 +- .../AddCreateImageAsJsonEntity.java} | 12 +- .../AddRebootTypeAsJsonEntity.java} | 14 +- .../AddResizeFlavorAsJsonEntity.java} | 14 +- .../AddRevertResizeAsJsonEntity.java} | 9 +- .../AddServerNameAsJsonEntity.java} | 14 +- .../AddSharedIpGroupAsJsonEntity.java} | 12 +- .../options/CreateServerOptions.java | 8 +- .../options/CreateSharedIpGroupOptions.java | 10 +- .../options/RebuildServerOptions.java | 10 +- .../CloudServersConnectionTest.java | 14 +- .../AddAdminPassAsJsonEntityTest.java} | 24 +- .../AddCreateImageAsJsonEntityTest.java} | 20 +- .../AddRebootTypeAsJsonEntityTest.java} | 28 +- .../AddServerNameAsJsonEntityTest.java} | 24 +- .../options/CreateServerOptionsTest.java | 4 +- .../CreateSharedIpGroupOptionsTest.java | 2 +- .../options/RebuildServerOptionsTest.java | 2 +- .../rackspace/RackspaceAuthentication.java | 4 +- .../RackspaceAuthenticationTest.java | 12 +- 117 files changed, 1248 insertions(+), 829 deletions(-) rename aws/s3/core/src/main/java/org/jclouds/aws/s3/{binders/AccessControlListBinder.java => decorators/AddACLAsXMLEntity.java} (94%) mode change 100644 => 100755 rename aws/s3/core/src/main/java/org/jclouds/aws/s3/{binders/S3ObjectBinder.java => decorators/AddS3ObjectEntity.java} (86%) mode change 100644 => 100755 rename azure/storage/blob/core/src/main/java/org/jclouds/azure/storage/blob/{binders/BlobBinder.java => decorators/AddBlobEntity.java} (85%) rename azure/storage/blob/core/src/main/java/org/jclouds/azure/storage/blob/{functions/MD5EnforcingBlobBinder.java => decorators/GenerateMD5AndAddBlobEntity.java} (81%) rename blobstore/core/src/main/java/org/jclouds/blobstore/{binders/BlobBinder.java => decorators/AddBlobEntity.java} (85%) rename mezeo/pcs2/core/src/main/java/org/jclouds/mezeo/pcs2/binders/PCSFileAsMultipartFormBinder.java => blobstore/core/src/main/java/org/jclouds/blobstore/decorators/AddBlobEntityAsMultipartForm.java (86%) rename blobstore/core/src/main/java/org/jclouds/blobstore/{binders/UserMetadataBinder.java => decorators/AddHeadersWithPrefix.java} (84%) rename {mezeo/pcs2/core/src/main/java/org/jclouds/mezeo/pcs2/functions => blobstore/core/src/main/java/org/jclouds/blobstore/domain}/Key.java (98%) rename mezeo/pcs2/core/src/test/java/org/jclouds/mezeo/pcs2/binders/PCSFileAsMultipartFormBinderTest.java => blobstore/core/src/test/java/org/jclouds/blobstore/decorators/AddBlobEntityAsMultipartFormTest.java (79%) create mode 100644 blobstore/core/src/test/java/org/jclouds/blobstore/util/BlobStoreUtilsTest.java rename core/src/main/java/org/jclouds/rest/{RestContext.java => InvocationContext.java} (97%) rename core/src/main/java/org/jclouds/rest/{EntityParam.java => annotations/DecoratorParam.java} (81%) mode change 100644 => 100755 rename core/src/main/java/org/jclouds/rest/{ => annotations}/Endpoint.java (97%) rename core/src/main/java/org/jclouds/rest/{ => annotations}/ExceptionParser.java (97%) mode change 100644 => 100755 rename core/src/main/java/org/jclouds/rest/{ => annotations}/Headers.java (98%) rename core/src/main/java/org/jclouds/rest/{ => annotations}/HostPrefixParam.java (98%) mode change 100644 => 100755 rename core/src/main/java/org/jclouds/rest/{ => annotations}/MapBinder.java (89%) rename core/src/main/java/org/jclouds/rest/{ => annotations}/MapEntityParam.java (91%) create mode 100644 core/src/main/java/org/jclouds/rest/annotations/MatrixParams.java rename core/src/main/java/org/jclouds/rest/{ => annotations}/ParamParser.java (97%) rename core/src/main/java/org/jclouds/rest/{ => annotations}/QueryParams.java (97%) rename core/src/main/java/org/jclouds/rest/{ => annotations}/RequestFilters.java (97%) mode change 100644 => 100755 rename core/src/main/java/org/jclouds/rest/{ => annotations}/ResponseParser.java (97%) mode change 100644 => 100755 rename core/src/main/java/org/jclouds/rest/{ => annotations}/SkipEncoding.java (97%) mode change 100644 => 100755 rename core/src/main/java/org/jclouds/rest/{ => annotations}/VirtualHost.java (97%) mode change 100644 => 100755 rename core/src/main/java/org/jclouds/rest/{ => annotations}/XMLResponseParser.java (97%) mode change 100644 => 100755 delete mode 100755 core/src/main/java/org/jclouds/rest/binders/HttpRequestOptionsBinder.java rename core/src/main/java/org/jclouds/rest/config/{JaxrsModule.java => RestModule.java} (95%) mode change 100644 => 100755 rename core/src/main/java/org/jclouds/rest/{binders/JsonBinder.java => decorators/AddAsJsonEntity.java} (84%) rename core/src/main/java/org/jclouds/rest/{binders/ToStringEntityBinder.java => decorators/AddAsStringEntity.java} (80%) rename core/src/main/java/org/jclouds/rest/{binders/MapEntityBinder.java => decorators/MapRequestDecorator.java} (87%) rename core/src/main/java/org/jclouds/rest/{binders/EntityBinder.java => decorators/RequestDecorator.java} (88%) rename core/src/main/java/org/jclouds/rest/{ => internal}/BoundedSortedSet.java (97%) rename core/src/main/java/org/jclouds/rest/{ => internal}/BoundedTreeSet.java (98%) rename core/src/main/java/org/jclouds/rest/{JaxrsAnnotationProcessor.java => internal/RestAnnotationProcessor.java} (70%) mode change 100644 => 100755 rename core/src/main/java/org/jclouds/rest/{ => internal}/RestClientProxy.java (92%) mode change 100644 => 100755 rename core/src/main/java/org/jclouds/rest/{ => internal}/RuntimeDelegateImpl.java (98%) mode change 100644 => 100755 rename core/src/test/java/org/jclouds/rest/{JaxrsAnnotationProcessorTest.java => RestAnnotationProcessorTest.java} (75%) mode change 100644 => 100755 rename mezeo/pcs2/core/src/main/java/org/jclouds/mezeo/pcs2/{binders/CreateContainerBinder.java => decorators/AddContainerNameAsXmlEntity.java} (85%) rename mezeo/pcs2/core/src/main/java/org/jclouds/mezeo/pcs2/{binders/BlockBinder.java => decorators/AddDataAndLength.java} (61%) rename mezeo/pcs2/core/src/main/java/org/jclouds/mezeo/pcs2/{binders/CreateFileBinder.java => decorators/AddFileInfoAsXmlEntity.java} (80%) rename mezeo/pcs2/core/src/test/java/org/jclouds/mezeo/pcs2/{binders/CreateContainerBinderTest.java => decorators/AddContainerNameAsXmlEntityTest.java} (83%) rename mezeo/pcs2/core/src/test/java/org/jclouds/mezeo/pcs2/{binders/CreateFileBinderTest.java => decorators/AddFileInfoAsXmlEntityTest.java} (86%) rename rackspace/cloudfiles/core/src/main/java/org/jclouds/rackspace/cloudfiles/{binders/CFObjectBinder.java => decorators/AddCFObjectEntity.java} (85%) rename rackspace/cloudservers/core/src/main/java/org/jclouds/rackspace/cloudservers/{binders/ChangeAdminPassBinder.java => decorators/AddAdminPassAsJsonEntity.java} (75%) rename rackspace/cloudservers/core/src/main/java/org/jclouds/rackspace/cloudservers/{binders/BackupScheduleBinder.java => decorators/AddBackupScheduleAsJsonEntity.java} (78%) rename rackspace/cloudservers/core/src/main/java/org/jclouds/rackspace/cloudservers/{binders/ConfirmResizeBinder.java => decorators/AddConfirmResizeAsJsonEntity.java} (85%) rename rackspace/cloudservers/core/src/main/java/org/jclouds/rackspace/cloudservers/{binders/CreateImageBinder.java => decorators/AddCreateImageAsJsonEntity.java} (81%) rename rackspace/cloudservers/core/src/main/java/org/jclouds/rackspace/cloudservers/{binders/RebootTypeBinder.java => decorators/AddRebootTypeAsJsonEntity.java} (76%) rename rackspace/cloudservers/core/src/main/java/org/jclouds/rackspace/cloudservers/{binders/ResizeBinder.java => decorators/AddResizeFlavorAsJsonEntity.java} (75%) rename rackspace/cloudservers/core/src/main/java/org/jclouds/rackspace/cloudservers/{binders/RevertResizeBinder.java => decorators/AddRevertResizeAsJsonEntity.java} (85%) rename rackspace/cloudservers/core/src/main/java/org/jclouds/rackspace/cloudservers/{binders/ChangeServerNameBinder.java => decorators/AddServerNameAsJsonEntity.java} (76%) rename rackspace/cloudservers/core/src/main/java/org/jclouds/rackspace/cloudservers/{binders/ShareIpBinder.java => decorators/AddSharedIpGroupAsJsonEntity.java} (81%) rename rackspace/cloudservers/core/src/test/java/org/jclouds/rackspace/cloudservers/{binders/ChangeAdminPassBinderTest.java => decorators/AddAdminPassAsJsonEntityTest.java} (77%) rename rackspace/cloudservers/core/src/test/java/org/jclouds/rackspace/cloudservers/{binders/CreateImageBinderTest.java => decorators/AddCreateImageAsJsonEntityTest.java} (77%) rename rackspace/cloudservers/core/src/test/java/org/jclouds/rackspace/cloudservers/{binders/RebootTypeBinderTest.java => decorators/AddRebootTypeAsJsonEntityTest.java} (75%) rename rackspace/cloudservers/core/src/test/java/org/jclouds/rackspace/cloudservers/{binders/ChangeServerNameBinderTest.java => decorators/AddServerNameAsJsonEntityTest.java} (76%) diff --git a/aws/s3/core/src/main/java/org/jclouds/aws/s3/S3BlobStore.java b/aws/s3/core/src/main/java/org/jclouds/aws/s3/S3BlobStore.java index 52dc60367e..7e506bb943 100644 --- a/aws/s3/core/src/main/java/org/jclouds/aws/s3/S3BlobStore.java +++ b/aws/s3/core/src/main/java/org/jclouds/aws/s3/S3BlobStore.java @@ -34,7 +34,7 @@ import javax.ws.rs.PUT; import javax.ws.rs.Path; import javax.ws.rs.PathParam; -import org.jclouds.aws.s3.binders.S3ObjectBinder; +import org.jclouds.aws.s3.decorators.AddS3ObjectEntity; import org.jclouds.aws.s3.domain.BucketMetadata; import org.jclouds.aws.s3.domain.ListBucketResponse; import org.jclouds.aws.s3.domain.ObjectMetadata; @@ -55,17 +55,17 @@ import org.jclouds.blobstore.functions.ThrowKeyNotFoundOn404; import org.jclouds.http.functions.ParseETagHeader; import org.jclouds.http.functions.ReturnFalseOn404; import org.jclouds.http.options.GetOptions; -import org.jclouds.rest.Endpoint; -import org.jclouds.rest.EntityParam; -import org.jclouds.rest.ExceptionParser; -import org.jclouds.rest.HostPrefixParam; -import org.jclouds.rest.ParamParser; -import org.jclouds.rest.QueryParams; -import org.jclouds.rest.RequestFilters; -import org.jclouds.rest.ResponseParser; -import org.jclouds.rest.SkipEncoding; -import org.jclouds.rest.VirtualHost; -import org.jclouds.rest.XMLResponseParser; +import org.jclouds.rest.annotations.DecoratorParam; +import org.jclouds.rest.annotations.Endpoint; +import org.jclouds.rest.annotations.ExceptionParser; +import org.jclouds.rest.annotations.HostPrefixParam; +import org.jclouds.rest.annotations.ParamParser; +import org.jclouds.rest.annotations.QueryParams; +import org.jclouds.rest.annotations.RequestFilters; +import org.jclouds.rest.annotations.ResponseParser; +import org.jclouds.rest.annotations.SkipEncoding; +import org.jclouds.rest.annotations.VirtualHost; +import org.jclouds.rest.annotations.XMLResponseParser; /** * Provides access to S3 via their REST API. @@ -181,7 +181,7 @@ public interface S3BlobStore extends BlobStore putBlob( @HostPrefixParam String bucketName, - @PathParam("key") @ParamParser(BlobKey.class) @EntityParam(S3ObjectBinder.class) S3Object object); + @PathParam("key") @ParamParser(BlobKey.class) @DecoratorParam(AddS3ObjectEntity.class) S3Object object); @PUT @Path("/") diff --git a/aws/s3/core/src/main/java/org/jclouds/aws/s3/S3Connection.java b/aws/s3/core/src/main/java/org/jclouds/aws/s3/S3Connection.java index e406ffbb22..40186806ab 100644 --- a/aws/s3/core/src/main/java/org/jclouds/aws/s3/S3Connection.java +++ b/aws/s3/core/src/main/java/org/jclouds/aws/s3/S3Connection.java @@ -34,8 +34,8 @@ import javax.ws.rs.PUT; import javax.ws.rs.Path; import javax.ws.rs.PathParam; -import org.jclouds.aws.s3.binders.AccessControlListBinder; -import org.jclouds.aws.s3.binders.S3ObjectBinder; +import org.jclouds.aws.s3.decorators.AddACLAsXMLEntity; +import org.jclouds.aws.s3.decorators.AddS3ObjectEntity; import org.jclouds.aws.s3.domain.AccessControlList; import org.jclouds.aws.s3.domain.BucketMetadata; import org.jclouds.aws.s3.domain.ListBucketResponse; @@ -62,21 +62,18 @@ import org.jclouds.blobstore.functions.ThrowKeyNotFoundOn404; import org.jclouds.http.functions.ParseETagHeader; import org.jclouds.http.functions.ReturnFalseOn404; import org.jclouds.http.options.GetOptions; -import org.jclouds.rest.Endpoint; -import org.jclouds.rest.EntityParam; -import org.jclouds.rest.ExceptionParser; -import org.jclouds.rest.Headers; -import org.jclouds.rest.HostPrefixParam; -import org.jclouds.rest.ParamParser; -import org.jclouds.rest.QueryParams; -import org.jclouds.rest.RequestFilters; -import org.jclouds.rest.ResponseParser; -import org.jclouds.rest.SkipEncoding; -import org.jclouds.rest.VirtualHost; -import org.jclouds.rest.XMLResponseParser; -import org.jclouds.rest.binders.HttpRequestOptionsBinder; - -import com.google.inject.internal.Nullable; +import org.jclouds.rest.annotations.DecoratorParam; +import org.jclouds.rest.annotations.Endpoint; +import org.jclouds.rest.annotations.ExceptionParser; +import org.jclouds.rest.annotations.Headers; +import org.jclouds.rest.annotations.HostPrefixParam; +import org.jclouds.rest.annotations.ParamParser; +import org.jclouds.rest.annotations.QueryParams; +import org.jclouds.rest.annotations.RequestFilters; +import org.jclouds.rest.annotations.ResponseParser; +import org.jclouds.rest.annotations.SkipEncoding; +import org.jclouds.rest.annotations.VirtualHost; +import org.jclouds.rest.annotations.XMLResponseParser; /** * Provides access to S3 via their REST API. @@ -209,7 +206,7 @@ public interface S3Connection { @ResponseParser(ParseETagHeader.class) Future putObject( @HostPrefixParam String bucketName, - @PathParam("key") @ParamParser(BlobKey.class) @EntityParam(S3ObjectBinder.class) S3Object object, + @PathParam("key") @ParamParser(BlobKey.class) @DecoratorParam(AddS3ObjectEntity.class) S3Object object, PutObjectOptions... options); /** @@ -237,7 +234,7 @@ public interface S3Connection { @Path("/") @ExceptionParser(ReturnTrueIfBucketAlreadyOwnedByYou.class) Future putBucketIfNotExists(@HostPrefixParam String bucketName, - @Nullable @EntityParam(HttpRequestOptionsBinder.class) PutBucketOptions... options); + PutBucketOptions... options); /** * Deletes the bucket, if it is empty. @@ -378,7 +375,7 @@ public interface S3Connection { @Path("/") @QueryParams(keys = "acl") Future putBucketACL(@HostPrefixParam String bucketName, - @EntityParam(AccessControlListBinder.class) AccessControlList acl); + @DecoratorParam(AddACLAsXMLEntity.class) AccessControlList acl); /** * A GET request operation directed at an object or bucket URI with the "acl" parameter retrieves @@ -421,6 +418,6 @@ public interface S3Connection { @QueryParams(keys = "acl") @Path("{key}") Future putObjectACL(@HostPrefixParam String bucketName, @PathParam("key") String key, - @EntityParam(AccessControlListBinder.class) AccessControlList acl); + @DecoratorParam(AddACLAsXMLEntity.class) AccessControlList acl); } diff --git a/aws/s3/core/src/main/java/org/jclouds/aws/s3/binders/AccessControlListBinder.java b/aws/s3/core/src/main/java/org/jclouds/aws/s3/decorators/AddACLAsXMLEntity.java old mode 100644 new mode 100755 similarity index 94% rename from aws/s3/core/src/main/java/org/jclouds/aws/s3/binders/AccessControlListBinder.java rename to aws/s3/core/src/main/java/org/jclouds/aws/s3/decorators/AddACLAsXMLEntity.java index 44d34e8b02..9c46111c0b --- a/aws/s3/core/src/main/java/org/jclouds/aws/s3/binders/AccessControlListBinder.java +++ b/aws/s3/core/src/main/java/org/jclouds/aws/s3/decorators/AddACLAsXMLEntity.java @@ -21,7 +21,7 @@ * under the License. * ==================================================================== */ -package org.jclouds.aws.s3.binders; +package org.jclouds.aws.s3.decorators; import java.util.Properties; @@ -37,14 +37,14 @@ import org.jclouds.aws.s3.domain.AccessControlList.Grant; import org.jclouds.aws.s3.domain.AccessControlList.GroupGrantee; import org.jclouds.aws.s3.reference.S3Constants; import org.jclouds.http.HttpRequest; -import org.jclouds.rest.binders.EntityBinder; +import org.jclouds.rest.decorators.RequestDecorator; import org.jclouds.util.Utils; import com.jamesmurty.utils.XMLBuilder; -public class AccessControlListBinder implements EntityBinder { +public class AddACLAsXMLEntity implements RequestDecorator { - public void addEntityToRequest(Object entity, HttpRequest request) { + public HttpRequest decorateRequest(HttpRequest request, Object entity) { AccessControlList from = (AccessControlList) entity; Properties outputProperties = new Properties(); outputProperties.put(javax.xml.transform.OutputKeys.OMIT_XML_DECLARATION, "yes"); @@ -57,6 +57,7 @@ public class AccessControlListBinder implements EntityBinder { Utils.rethrowIfRuntime(e); throw new RuntimeException("error transforming acl: " + from, e); } + return request; } protected XMLBuilder generateBuilder(AccessControlList acl) throws ParserConfigurationException, diff --git a/aws/s3/core/src/main/java/org/jclouds/aws/s3/binders/S3ObjectBinder.java b/aws/s3/core/src/main/java/org/jclouds/aws/s3/decorators/AddS3ObjectEntity.java old mode 100644 new mode 100755 similarity index 86% rename from aws/s3/core/src/main/java/org/jclouds/aws/s3/binders/S3ObjectBinder.java rename to aws/s3/core/src/main/java/org/jclouds/aws/s3/decorators/AddS3ObjectEntity.java index c1f803fe58..441037f400 --- a/aws/s3/core/src/main/java/org/jclouds/aws/s3/binders/S3ObjectBinder.java +++ b/aws/s3/core/src/main/java/org/jclouds/aws/s3/decorators/AddS3ObjectEntity.java @@ -21,28 +21,27 @@ * under the License. * ==================================================================== */ -package org.jclouds.aws.s3.binders; +package org.jclouds.aws.s3.decorators; import static com.google.common.base.Preconditions.checkArgument; import static org.jclouds.blobstore.reference.BlobStoreConstants.PROPERTY_USER_METADATA_PREFIX; +import javax.inject.Inject; +import javax.inject.Named; import javax.ws.rs.core.HttpHeaders; import org.jclouds.aws.s3.domain.S3Object; -import org.jclouds.blobstore.binders.BlobBinder; +import org.jclouds.blobstore.decorators.AddBlobEntity; import org.jclouds.blobstore.domain.Blob; import org.jclouds.http.HttpRequest; -import javax.inject.Inject; -import javax.inject.Named; - -public class S3ObjectBinder extends BlobBinder { +public class AddS3ObjectEntity extends AddBlobEntity { @Inject - public S3ObjectBinder(@Named(PROPERTY_USER_METADATA_PREFIX) String metadataPrefix) { + public AddS3ObjectEntity(@Named(PROPERTY_USER_METADATA_PREFIX) String metadataPrefix) { super(metadataPrefix); } - public void addEntityToRequest(Object entity, HttpRequest request) { + public HttpRequest decorateRequest(HttpRequest request, Object entity) { Blob object = (Blob) entity; checkArgument(object.getMetadata().getSize() >= 0, "size must be set"); checkArgument(object.getContentLength() <= 5 * 1024 * 1024 * 1024, @@ -64,6 +63,6 @@ public class S3ObjectBinder extends BlobBinder { s3Object.getMetadata().getContentEncoding()); } } - super.addEntityToRequest(entity, request); + return super.decorateRequest(request, entity); } } diff --git a/aws/s3/core/src/main/java/org/jclouds/aws/s3/domain/ListBucketResponse.java b/aws/s3/core/src/main/java/org/jclouds/aws/s3/domain/ListBucketResponse.java index f9029d8385..9c8d92bcd7 100644 --- a/aws/s3/core/src/main/java/org/jclouds/aws/s3/domain/ListBucketResponse.java +++ b/aws/s3/core/src/main/java/org/jclouds/aws/s3/domain/ListBucketResponse.java @@ -48,7 +48,7 @@ import java.util.SortedSet; * @author Adrian Cole * @see */ -public interface ListBucketResponse extends org.jclouds.rest.BoundedSortedSet { +public interface ListBucketResponse extends org.jclouds.rest.internal.BoundedSortedSet { /** * Example: diff --git a/aws/s3/core/src/main/java/org/jclouds/aws/s3/domain/TreeSetListBucketResponse.java b/aws/s3/core/src/main/java/org/jclouds/aws/s3/domain/TreeSetListBucketResponse.java index 6605df87f3..64f2deed03 100644 --- a/aws/s3/core/src/main/java/org/jclouds/aws/s3/domain/TreeSetListBucketResponse.java +++ b/aws/s3/core/src/main/java/org/jclouds/aws/s3/domain/TreeSetListBucketResponse.java @@ -30,7 +30,7 @@ import java.util.SortedSet; * @author Adrian Cole * */ -public class TreeSetListBucketResponse extends org.jclouds.rest.BoundedTreeSet +public class TreeSetListBucketResponse extends org.jclouds.rest.internal.BoundedTreeSet implements ListBucketResponse { /** The serialVersionUID */ private static final long serialVersionUID = -4475709781001190244L; diff --git a/azure/storage/blob/core/src/main/java/org/jclouds/azure/storage/blob/AzureBlobConnection.java b/azure/storage/blob/core/src/main/java/org/jclouds/azure/storage/blob/AzureBlobConnection.java index f3b1e3e510..d4758ac5a1 100644 --- a/azure/storage/blob/core/src/main/java/org/jclouds/azure/storage/blob/AzureBlobConnection.java +++ b/azure/storage/blob/core/src/main/java/org/jclouds/azure/storage/blob/AzureBlobConnection.java @@ -50,24 +50,24 @@ import org.jclouds.azure.storage.domain.BoundedSortedSet; import org.jclouds.azure.storage.filters.SharedKeyAuthentication; import org.jclouds.azure.storage.options.ListOptions; import org.jclouds.azure.storage.reference.AzureStorageHeaders; -import org.jclouds.blobstore.binders.BlobBinder; -import org.jclouds.blobstore.binders.UserMetadataBinder; +import org.jclouds.blobstore.decorators.AddBlobEntity; +import org.jclouds.blobstore.decorators.AddHeadersWithPrefix; import org.jclouds.blobstore.functions.BlobKey; import org.jclouds.blobstore.functions.ReturnVoidOnNotFoundOr404; import org.jclouds.blobstore.functions.ThrowKeyNotFoundOn404; import org.jclouds.http.functions.ParseETagHeader; import org.jclouds.http.functions.ReturnTrueOn404; import org.jclouds.http.options.GetOptions; -import org.jclouds.rest.Endpoint; -import org.jclouds.rest.EntityParam; -import org.jclouds.rest.ExceptionParser; -import org.jclouds.rest.Headers; -import org.jclouds.rest.ParamParser; -import org.jclouds.rest.QueryParams; -import org.jclouds.rest.RequestFilters; -import org.jclouds.rest.ResponseParser; -import org.jclouds.rest.SkipEncoding; -import org.jclouds.rest.XMLResponseParser; +import org.jclouds.rest.annotations.DecoratorParam; +import org.jclouds.rest.annotations.Endpoint; +import org.jclouds.rest.annotations.ExceptionParser; +import org.jclouds.rest.annotations.Headers; +import org.jclouds.rest.annotations.ParamParser; +import org.jclouds.rest.annotations.QueryParams; +import org.jclouds.rest.annotations.RequestFilters; +import org.jclouds.rest.annotations.ResponseParser; +import org.jclouds.rest.annotations.SkipEncoding; +import org.jclouds.rest.annotations.XMLResponseParser; import com.google.common.collect.Multimap; @@ -144,7 +144,7 @@ public interface AzureBlobConnection { @Path("{container}") @QueryParams(keys = { "restype", "comp" }, values = { "container", "metadata" }) void setContainerMetadata(@PathParam("container") String container, - @EntityParam(UserMetadataBinder.class) Multimap metadata); + @DecoratorParam(AddHeadersWithPrefix.class) Multimap metadata); /** * The Delete Container operation marks the specified container for deletion. The container and @@ -272,7 +272,7 @@ public interface AzureBlobConnection { @Path("{container}/{key}") @ResponseParser(ParseETagHeader.class) Future putBlob(@PathParam("container") String container, - @PathParam("key") @ParamParser(BlobKey.class) @EntityParam(BlobBinder.class) Blob object); + @PathParam("key") @ParamParser(BlobKey.class) @DecoratorParam(AddBlobEntity.class) Blob object); /** * The Get Blob operation reads or downloads a blob from the system, including its metadata and @@ -302,7 +302,7 @@ public interface AzureBlobConnection { @Path("{container}/{key}") @QueryParams(keys = { "comp" }, values = { "metadata" }) void setBlobMetadata(@PathParam("container") String container, @PathParam("key") String key, - @EntityParam(UserMetadataBinder.class) Multimap metadata); + @DecoratorParam(AddHeadersWithPrefix.class) Multimap metadata); /** * The Delete Blob operation marks the specified blob for deletion. The blob is later deleted diff --git a/azure/storage/blob/core/src/main/java/org/jclouds/azure/storage/blob/AzureBlobStore.java b/azure/storage/blob/core/src/main/java/org/jclouds/azure/storage/blob/AzureBlobStore.java index 34a70ce2c2..de4f237ac7 100644 --- a/azure/storage/blob/core/src/main/java/org/jclouds/azure/storage/blob/AzureBlobStore.java +++ b/azure/storage/blob/core/src/main/java/org/jclouds/azure/storage/blob/AzureBlobStore.java @@ -35,11 +35,11 @@ import javax.ws.rs.Path; import javax.ws.rs.PathParam; import org.jclouds.azure.storage.AzureBlob; +import org.jclouds.azure.storage.blob.decorators.GenerateMD5AndAddBlobEntity; import org.jclouds.azure.storage.blob.domain.Blob; import org.jclouds.azure.storage.blob.domain.BlobMetadata; import org.jclouds.azure.storage.blob.domain.ContainerMetadata; import org.jclouds.azure.storage.blob.domain.ListBlobsResponse; -import org.jclouds.azure.storage.blob.functions.MD5EnforcingBlobBinder; import org.jclouds.azure.storage.blob.functions.ParseBlobFromHeadersAndHttpContent; import org.jclouds.azure.storage.blob.functions.ParseBlobMetadataFromHeaders; import org.jclouds.azure.storage.blob.functions.ReturnTrueIfContainerAlreadyExists; @@ -56,16 +56,16 @@ import org.jclouds.blobstore.functions.ThrowKeyNotFoundOn404; import org.jclouds.http.functions.ParseETagHeader; import org.jclouds.http.functions.ReturnFalseOn404; import org.jclouds.http.options.GetOptions; -import org.jclouds.rest.Endpoint; -import org.jclouds.rest.EntityParam; -import org.jclouds.rest.ExceptionParser; -import org.jclouds.rest.Headers; -import org.jclouds.rest.ParamParser; -import org.jclouds.rest.QueryParams; -import org.jclouds.rest.RequestFilters; -import org.jclouds.rest.ResponseParser; -import org.jclouds.rest.SkipEncoding; -import org.jclouds.rest.XMLResponseParser; +import org.jclouds.rest.annotations.DecoratorParam; +import org.jclouds.rest.annotations.Endpoint; +import org.jclouds.rest.annotations.ExceptionParser; +import org.jclouds.rest.annotations.Headers; +import org.jclouds.rest.annotations.ParamParser; +import org.jclouds.rest.annotations.QueryParams; +import org.jclouds.rest.annotations.RequestFilters; +import org.jclouds.rest.annotations.ResponseParser; +import org.jclouds.rest.annotations.SkipEncoding; +import org.jclouds.rest.annotations.XMLResponseParser; /** * Provides access to Azure Blob via their REST API. @@ -149,7 +149,7 @@ public interface AzureBlobStore extends BlobStore putBlob( @PathParam("container") String container, - @PathParam("key") @ParamParser(BlobKey.class) @EntityParam(MD5EnforcingBlobBinder.class) Blob object); + @PathParam("key") @ParamParser(BlobKey.class) @DecoratorParam(GenerateMD5AndAddBlobEntity.class) Blob object); @GET @ResponseParser(ParseBlobFromHeadersAndHttpContent.class) diff --git a/azure/storage/blob/core/src/main/java/org/jclouds/azure/storage/blob/AzureBlobUtil.java b/azure/storage/blob/core/src/main/java/org/jclouds/azure/storage/blob/AzureBlobUtil.java index 38d8e686b4..a40a963351 100644 --- a/azure/storage/blob/core/src/main/java/org/jclouds/azure/storage/blob/AzureBlobUtil.java +++ b/azure/storage/blob/core/src/main/java/org/jclouds/azure/storage/blob/AzureBlobUtil.java @@ -33,12 +33,12 @@ import org.jclouds.azure.storage.filters.SharedKeyAuthentication; import org.jclouds.azure.storage.reference.AzureStorageHeaders; import org.jclouds.blobstore.functions.ThrowKeyNotFoundOn404; import org.jclouds.http.functions.ParseContentMD5FromHeaders; -import org.jclouds.rest.Endpoint; -import org.jclouds.rest.ExceptionParser; -import org.jclouds.rest.Headers; -import org.jclouds.rest.RequestFilters; -import org.jclouds.rest.ResponseParser; -import org.jclouds.rest.SkipEncoding; +import org.jclouds.rest.annotations.Endpoint; +import org.jclouds.rest.annotations.ExceptionParser; +import org.jclouds.rest.annotations.Headers; +import org.jclouds.rest.annotations.RequestFilters; +import org.jclouds.rest.annotations.ResponseParser; +import org.jclouds.rest.annotations.SkipEncoding; /** * Helper functions needed to to derive BlobStore values diff --git a/azure/storage/blob/core/src/main/java/org/jclouds/azure/storage/blob/binders/BlobBinder.java b/azure/storage/blob/core/src/main/java/org/jclouds/azure/storage/blob/decorators/AddBlobEntity.java similarity index 85% rename from azure/storage/blob/core/src/main/java/org/jclouds/azure/storage/blob/binders/BlobBinder.java rename to azure/storage/blob/core/src/main/java/org/jclouds/azure/storage/blob/decorators/AddBlobEntity.java index 7fa0f4808f..532c2f6933 100644 --- a/azure/storage/blob/core/src/main/java/org/jclouds/azure/storage/blob/binders/BlobBinder.java +++ b/azure/storage/blob/core/src/main/java/org/jclouds/azure/storage/blob/decorators/AddBlobEntity.java @@ -21,27 +21,27 @@ * under the License. * ==================================================================== */ -package org.jclouds.azure.storage.blob.binders; +package org.jclouds.azure.storage.blob.decorators; import static com.google.common.base.Preconditions.checkArgument; import static org.jclouds.blobstore.reference.BlobStoreConstants.PROPERTY_USER_METADATA_PREFIX; +import javax.inject.Inject; +import javax.inject.Named; import javax.ws.rs.core.HttpHeaders; import org.jclouds.azure.storage.blob.domain.BlobMetadata; import org.jclouds.blobstore.domain.Blob; import org.jclouds.http.HttpRequest; -import javax.inject.Inject; -import javax.inject.Named; - -public class BlobBinder extends org.jclouds.blobstore.binders.BlobBinder { +public class AddBlobEntity extends org.jclouds.blobstore.decorators.AddBlobEntity { @Inject - public BlobBinder(@Named(PROPERTY_USER_METADATA_PREFIX) String metadataPrefix) { + public AddBlobEntity(@Named(PROPERTY_USER_METADATA_PREFIX) String metadataPrefix) { super(metadataPrefix); } - public void addEntityToRequest(Object entity, HttpRequest request) { + @Override + public HttpRequest decorateRequest(HttpRequest request, Object entity) { Blob object = (Blob) entity; checkArgument(object.getMetadata().getSize() >= 0, "size must be set"); checkArgument(object.getContentLength() <= 64 * 1024 * 1024, @@ -57,6 +57,6 @@ public class BlobBinder extends org.jclouds.blobstore.binders.BlobBinder { request.getHeaders().put(HttpHeaders.CONTENT_ENCODING, md.getContentEncoding()); } } - super.addEntityToRequest(entity, request); + return super.decorateRequest(request, entity); } } diff --git a/azure/storage/blob/core/src/main/java/org/jclouds/azure/storage/blob/functions/MD5EnforcingBlobBinder.java b/azure/storage/blob/core/src/main/java/org/jclouds/azure/storage/blob/decorators/GenerateMD5AndAddBlobEntity.java similarity index 81% rename from azure/storage/blob/core/src/main/java/org/jclouds/azure/storage/blob/functions/MD5EnforcingBlobBinder.java rename to azure/storage/blob/core/src/main/java/org/jclouds/azure/storage/blob/decorators/GenerateMD5AndAddBlobEntity.java index 117c7f1fc2..e284033297 100644 --- a/azure/storage/blob/core/src/main/java/org/jclouds/azure/storage/blob/functions/MD5EnforcingBlobBinder.java +++ b/azure/storage/blob/core/src/main/java/org/jclouds/azure/storage/blob/decorators/GenerateMD5AndAddBlobEntity.java @@ -21,7 +21,7 @@ * under the License. * ==================================================================== */ -package org.jclouds.azure.storage.blob.functions; +package org.jclouds.azure.storage.blob.decorators; import static org.jclouds.blobstore.reference.BlobStoreConstants.PROPERTY_USER_METADATA_PREFIX; @@ -30,18 +30,18 @@ import java.io.IOException; import javax.inject.Inject; import javax.inject.Named; -import org.jclouds.azure.storage.blob.binders.BlobBinder; import org.jclouds.blobstore.domain.Blob; import org.jclouds.http.HttpRequest; -public class MD5EnforcingBlobBinder extends BlobBinder { +public class GenerateMD5AndAddBlobEntity extends AddBlobEntity { @Inject - public MD5EnforcingBlobBinder(@Named(PROPERTY_USER_METADATA_PREFIX) String metadataPrefix) { + public GenerateMD5AndAddBlobEntity(@Named(PROPERTY_USER_METADATA_PREFIX) String metadataPrefix) { super(metadataPrefix); } - public void addEntityToRequest(Object entity, HttpRequest request) { + @Override + public HttpRequest decorateRequest(HttpRequest request, Object entity) { Blob object = (Blob) entity; if (object.getMetadata().getContentMD5() == null) { try { @@ -50,6 +50,6 @@ public class MD5EnforcingBlobBinder extends BlobBinder { throw new RuntimeException("Could not generate MD5 for " + object.getKey(), e); } } - super.addEntityToRequest(entity, request); + return super.decorateRequest(request, entity); } } diff --git a/azure/storage/blob/core/src/main/java/org/jclouds/azure/storage/blob/functions/ParseContainerMetadataFromHeaders.java b/azure/storage/blob/core/src/main/java/org/jclouds/azure/storage/blob/functions/ParseContainerMetadataFromHeaders.java index 0d232a5345..9bcac2ce9e 100644 --- a/azure/storage/blob/core/src/main/java/org/jclouds/azure/storage/blob/functions/ParseContainerMetadataFromHeaders.java +++ b/azure/storage/blob/core/src/main/java/org/jclouds/azure/storage/blob/functions/ParseContainerMetadataFromHeaders.java @@ -36,7 +36,7 @@ import org.jclouds.http.HttpException; import org.jclouds.http.HttpRequest; import org.jclouds.http.HttpResponse; import org.jclouds.http.HttpUtils; -import org.jclouds.rest.RestContext; +import org.jclouds.rest.InvocationContext; import org.jclouds.util.DateService; import com.google.common.annotations.VisibleForTesting; @@ -50,7 +50,7 @@ import com.google.common.base.Function; * @author Adrian Cole */ public class ParseContainerMetadataFromHeaders implements - Function, RestContext { + Function, InvocationContext { private final DateService dateParser; private final String metadataPrefix; diff --git a/azure/storage/blob/core/src/test/java/org/jclouds/azure/storage/blob/AzureBlobConnectionTest.java b/azure/storage/blob/core/src/test/java/org/jclouds/azure/storage/blob/AzureBlobConnectionTest.java index df4835d5f6..3b8bf7bca9 100644 --- a/azure/storage/blob/core/src/test/java/org/jclouds/azure/storage/blob/AzureBlobConnectionTest.java +++ b/azure/storage/blob/core/src/test/java/org/jclouds/azure/storage/blob/AzureBlobConnectionTest.java @@ -33,6 +33,7 @@ import java.net.URI; import java.util.Collections; import javax.ws.rs.HttpMethod; +import javax.ws.rs.core.HttpHeaders; import org.jclouds.azure.storage.AzureBlob; import org.jclouds.azure.storage.blob.functions.ParseContainerMetadataFromHeaders; @@ -52,8 +53,8 @@ import org.jclouds.http.functions.ParseSax; import org.jclouds.http.functions.ReturnTrueIf2xx; import org.jclouds.http.functions.ReturnTrueOn404; import org.jclouds.http.functions.ReturnVoidIf2xx; -import org.jclouds.rest.JaxrsAnnotationProcessor; -import org.jclouds.rest.config.JaxrsModule; +import org.jclouds.rest.config.RestModule; +import org.jclouds.rest.internal.RestAnnotationProcessor; import org.jclouds.util.Jsr330; import org.testng.annotations.BeforeClass; import org.testng.annotations.Test; @@ -300,7 +301,9 @@ public class AzureBlobConnectionTest { assertEquals(httpMethod.getEndpoint().getPath(), "/container"); assertEquals(httpMethod.getEndpoint().getQuery(), "restype=container&comp=metadata"); assertEquals(httpMethod.getMethod(), HttpMethod.PUT); - assertEquals(httpMethod.getHeaders().size(), 2); + assertEquals(httpMethod.getHeaders().size(), 3); + assertEquals(httpMethod.getHeaders().get(HttpHeaders.CONTENT_LENGTH), Collections + .singletonList("0")); assertEquals(httpMethod.getHeaders().get("x-ms-version"), Collections .singletonList("2009-07-17")); assertEquals(httpMethod.getHeaders().get("x-ms-meta-key"), Collections.singletonList("value")); @@ -319,9 +322,11 @@ public class AzureBlobConnectionTest { assertEquals(httpMethod.getEndpoint().getPath(), "/container/blob"); assertEquals(httpMethod.getEndpoint().getQuery(), "comp=metadata"); assertEquals(httpMethod.getMethod(), HttpMethod.PUT); - assertEquals(httpMethod.getHeaders().size(), 2); + assertEquals(httpMethod.getHeaders().size(), 3); assertEquals(httpMethod.getHeaders().get("x-ms-version"), Collections .singletonList("2009-07-17")); + assertEquals(httpMethod.getHeaders().get(HttpHeaders.CONTENT_LENGTH), Collections + .singletonList("0")); assertEquals(httpMethod.getHeaders().get("x-ms-meta-key"), Collections.singletonList("value")); assertEquals(processor.createResponseParser(method, httpMethod, null).getClass(), @@ -346,12 +351,12 @@ public class AzureBlobConnectionTest { Jsr330.named(BlobStoreConstants.PROPERTY_USER_METADATA_PREFIX)).to( "x-ms-meta-"); } - }, new JaxrsModule(), new ExecutorServiceModule(new WithinThreadExecutorService()), + }, new RestModule(), new ExecutorServiceModule(new WithinThreadExecutorService()), new JavaUrlHttpCommandExecutorServiceModule()); processor = injector.getInstance(Key - .get(new TypeLiteral>() { + .get(new TypeLiteral>() { })); } - JaxrsAnnotationProcessor processor; + RestAnnotationProcessor processor; } diff --git a/azure/storage/blob/core/src/test/java/org/jclouds/azure/storage/blob/AzureBlobStoreTest.java b/azure/storage/blob/core/src/test/java/org/jclouds/azure/storage/blob/AzureBlobStoreTest.java index cf6dcd79ef..6b133b9e07 100644 --- a/azure/storage/blob/core/src/test/java/org/jclouds/azure/storage/blob/AzureBlobStoreTest.java +++ b/azure/storage/blob/core/src/test/java/org/jclouds/azure/storage/blob/AzureBlobStoreTest.java @@ -49,8 +49,8 @@ import org.jclouds.http.functions.ParseETagHeader; import org.jclouds.http.functions.ParseSax; import org.jclouds.http.functions.ReturnTrueIf2xx; import org.jclouds.http.functions.ReturnVoidIf2xx; -import org.jclouds.rest.JaxrsAnnotationProcessor; -import org.jclouds.rest.config.JaxrsModule; +import org.jclouds.rest.config.RestModule; +import org.jclouds.rest.internal.RestAnnotationProcessor; import org.jclouds.util.Jsr330; import org.testng.annotations.BeforeClass; import org.testng.annotations.Test; @@ -195,12 +195,12 @@ public class AzureBlobStoreTest { }; } - }, new JaxrsModule(), new ExecutorServiceModule(new WithinThreadExecutorService()), + }, new RestModule(), new ExecutorServiceModule(new WithinThreadExecutorService()), new JavaUrlHttpCommandExecutorServiceModule()); processor = injector.getInstance(Key - .get(new TypeLiteral>() { + .get(new TypeLiteral>() { })); } - JaxrsAnnotationProcessor processor; + RestAnnotationProcessor processor; } diff --git a/azure/storage/core/src/main/java/org/jclouds/azure/storage/domain/BoundedSortedSet.java b/azure/storage/core/src/main/java/org/jclouds/azure/storage/domain/BoundedSortedSet.java index 26e3a1fd73..b5cc324048 100644 --- a/azure/storage/core/src/main/java/org/jclouds/azure/storage/domain/BoundedSortedSet.java +++ b/azure/storage/core/src/main/java/org/jclouds/azure/storage/domain/BoundedSortedSet.java @@ -28,7 +28,7 @@ package org.jclouds.azure.storage.domain; * @author Adrian Cole * */ -public interface BoundedSortedSet extends org.jclouds.rest.BoundedSortedSet { +public interface BoundedSortedSet extends org.jclouds.rest.internal.BoundedSortedSet { String getNextMarker(); diff --git a/azure/storage/core/src/main/java/org/jclouds/azure/storage/domain/BoundedTreeSet.java b/azure/storage/core/src/main/java/org/jclouds/azure/storage/domain/BoundedTreeSet.java index b0a170d97c..d34ee76404 100644 --- a/azure/storage/core/src/main/java/org/jclouds/azure/storage/domain/BoundedTreeSet.java +++ b/azure/storage/core/src/main/java/org/jclouds/azure/storage/domain/BoundedTreeSet.java @@ -30,7 +30,7 @@ import java.util.SortedSet; * @author Adrian Cole * */ -public class BoundedTreeSet extends org.jclouds.rest.BoundedTreeSet implements +public class BoundedTreeSet extends org.jclouds.rest.internal.BoundedTreeSet implements BoundedSortedSet { /** The serialVersionUID */ private static final long serialVersionUID = -4475709781001190244L; diff --git a/azure/storage/core/src/test/java/org/jclouds/azure/storage/filters/SharedKeyAuthenticationLiveTest.java b/azure/storage/core/src/test/java/org/jclouds/azure/storage/filters/SharedKeyAuthenticationLiveTest.java index 5e8f7a40fc..6c3f659a09 100644 --- a/azure/storage/core/src/test/java/org/jclouds/azure/storage/filters/SharedKeyAuthenticationLiveTest.java +++ b/azure/storage/core/src/test/java/org/jclouds/azure/storage/filters/SharedKeyAuthenticationLiveTest.java @@ -37,11 +37,11 @@ import org.jclouds.concurrent.WithinThreadExecutorService; import org.jclouds.concurrent.config.ExecutorServiceModule; import org.jclouds.http.config.JavaUrlHttpCommandExecutorServiceModule; import org.jclouds.logging.log4j.config.Log4JLoggingModule; -import org.jclouds.rest.Endpoint; -import org.jclouds.rest.QueryParams; -import org.jclouds.rest.RequestFilters; import org.jclouds.rest.RestClientFactory; -import org.jclouds.rest.config.JaxrsModule; +import org.jclouds.rest.annotations.Endpoint; +import org.jclouds.rest.annotations.QueryParams; +import org.jclouds.rest.annotations.RequestFilters; +import org.jclouds.rest.config.RestModule; import org.jclouds.util.Jsr330; import org.testng.annotations.BeforeClass; import org.testng.annotations.Test; @@ -96,7 +96,7 @@ public class SharedKeyAuthenticationLiveTest { Jsr330.named(AzureStorageConstants.PROPERTY_AZURESTORAGE_KEY)).to(key); } - }, new JaxrsModule(), new Log4JLoggingModule(), new ExecutorServiceModule( + }, new RestModule(), new Log4JLoggingModule(), new ExecutorServiceModule( new WithinThreadExecutorService()), new JavaUrlHttpCommandExecutorServiceModule()); RestClientFactory factory = injector.getInstance(RestClientFactory.class); client = factory.create(IntegrationTestClient.class); diff --git a/azure/storage/queue/core/src/main/java/org/jclouds/azure/storage/queue/AzureQueueConnection.java b/azure/storage/queue/core/src/main/java/org/jclouds/azure/storage/queue/AzureQueueConnection.java index 80b687c320..2366cbfbbc 100644 --- a/azure/storage/queue/core/src/main/java/org/jclouds/azure/storage/queue/AzureQueueConnection.java +++ b/azure/storage/queue/core/src/main/java/org/jclouds/azure/storage/queue/AzureQueueConnection.java @@ -40,12 +40,12 @@ import org.jclouds.azure.storage.options.ListOptions; import org.jclouds.azure.storage.queue.domain.QueueMetadata; import org.jclouds.azure.storage.queue.xml.AccountNameEnumerationResultsHandler; import org.jclouds.azure.storage.reference.AzureStorageHeaders; -import org.jclouds.rest.Endpoint; -import org.jclouds.rest.Headers; -import org.jclouds.rest.QueryParams; -import org.jclouds.rest.RequestFilters; -import org.jclouds.rest.SkipEncoding; -import org.jclouds.rest.XMLResponseParser; +import org.jclouds.rest.annotations.Endpoint; +import org.jclouds.rest.annotations.Headers; +import org.jclouds.rest.annotations.QueryParams; +import org.jclouds.rest.annotations.RequestFilters; +import org.jclouds.rest.annotations.SkipEncoding; +import org.jclouds.rest.annotations.XMLResponseParser; /** * Provides access to Azure Queue via their REST API. diff --git a/azure/storage/queue/core/src/test/java/org/jclouds/azure/storage/queue/AzureQueueConnectionTest.java b/azure/storage/queue/core/src/test/java/org/jclouds/azure/storage/queue/AzureQueueConnectionTest.java index 53dedcbbe3..1388594734 100644 --- a/azure/storage/queue/core/src/test/java/org/jclouds/azure/storage/queue/AzureQueueConnectionTest.java +++ b/azure/storage/queue/core/src/test/java/org/jclouds/azure/storage/queue/AzureQueueConnectionTest.java @@ -44,8 +44,8 @@ import org.jclouds.http.HttpUtils; import org.jclouds.http.config.JavaUrlHttpCommandExecutorServiceModule; import org.jclouds.http.functions.ParseSax; import org.jclouds.http.functions.ReturnTrueIf2xx; -import org.jclouds.rest.JaxrsAnnotationProcessor; -import org.jclouds.rest.config.JaxrsModule; +import org.jclouds.rest.config.RestModule; +import org.jclouds.rest.internal.RestAnnotationProcessor; import org.jclouds.util.Jsr330; import org.testng.annotations.BeforeClass; import org.testng.annotations.Test; @@ -177,12 +177,12 @@ public class AzureQueueConnectionTest { Jsr330.named(AzureStorageConstants.PROPERTY_AZURESTORAGE_KEY)).to( HttpUtils.toBase64String("key".getBytes())); } - }, new JaxrsModule(), new ExecutorServiceModule(new WithinThreadExecutorService()), + }, new RestModule(), new ExecutorServiceModule(new WithinThreadExecutorService()), new JavaUrlHttpCommandExecutorServiceModule()); processor = injector.getInstance(Key - .get(new TypeLiteral>() { + .get(new TypeLiteral>() { })); } - JaxrsAnnotationProcessor processor; + RestAnnotationProcessor processor; } diff --git a/blobstore/core/src/main/java/org/jclouds/blobstore/binders/BlobBinder.java b/blobstore/core/src/main/java/org/jclouds/blobstore/decorators/AddBlobEntity.java similarity index 85% rename from blobstore/core/src/main/java/org/jclouds/blobstore/binders/BlobBinder.java rename to blobstore/core/src/main/java/org/jclouds/blobstore/decorators/AddBlobEntity.java index 6a591f310d..0aa22e73e0 100644 --- a/blobstore/core/src/main/java/org/jclouds/blobstore/binders/BlobBinder.java +++ b/blobstore/core/src/main/java/org/jclouds/blobstore/decorators/AddBlobEntity.java @@ -21,9 +21,9 @@ * under the License. * ==================================================================== */ -package org.jclouds.blobstore.binders; +package org.jclouds.blobstore.decorators; -import static com.google.common.base.Preconditions.*; +import static com.google.common.base.Preconditions.checkNotNull; import static org.jclouds.blobstore.reference.BlobStoreConstants.PROPERTY_USER_METADATA_PREFIX; import javax.inject.Inject; @@ -33,17 +33,17 @@ import javax.ws.rs.core.HttpHeaders; import org.jclouds.blobstore.domain.Blob; import org.jclouds.http.HttpRequest; import org.jclouds.http.HttpUtils; -import org.jclouds.rest.binders.EntityBinder; +import org.jclouds.rest.decorators.RequestDecorator; -public class BlobBinder implements EntityBinder { +public class AddBlobEntity implements RequestDecorator { private final String metadataPrefix; @Inject - public BlobBinder(@Named(PROPERTY_USER_METADATA_PREFIX) String metadataPrefix) { + public AddBlobEntity(@Named(PROPERTY_USER_METADATA_PREFIX) String metadataPrefix) { this.metadataPrefix = metadataPrefix; } - public void addEntityToRequest(Object entity, HttpRequest request) { + public HttpRequest decorateRequest(HttpRequest request, Object entity) { Blob object = (Blob) entity; for (String key : object.getMetadata().getUserMetadata().keySet()) { @@ -63,6 +63,6 @@ public class BlobBinder implements EntityBinder { request.getHeaders().put("Content-MD5", HttpUtils.toBase64String(object.getMetadata().getContentMD5())); } - + return request; } } diff --git a/mezeo/pcs2/core/src/main/java/org/jclouds/mezeo/pcs2/binders/PCSFileAsMultipartFormBinder.java b/blobstore/core/src/main/java/org/jclouds/blobstore/decorators/AddBlobEntityAsMultipartForm.java similarity index 86% rename from mezeo/pcs2/core/src/main/java/org/jclouds/mezeo/pcs2/binders/PCSFileAsMultipartFormBinder.java rename to blobstore/core/src/main/java/org/jclouds/blobstore/decorators/AddBlobEntityAsMultipartForm.java index 10da356211..1cad374707 100644 --- a/mezeo/pcs2/core/src/main/java/org/jclouds/mezeo/pcs2/binders/PCSFileAsMultipartFormBinder.java +++ b/blobstore/core/src/main/java/org/jclouds/blobstore/decorators/AddBlobEntityAsMultipartForm.java @@ -21,7 +21,7 @@ * under the License. * ==================================================================== */ -package org.jclouds.mezeo.pcs2.binders; +package org.jclouds.blobstore.decorators; import static com.google.common.base.Preconditions.checkNotNull; @@ -32,12 +32,12 @@ import java.io.InputStream; import javax.ws.rs.core.HttpHeaders; import org.jclouds.blobstore.domain.Blob; +import org.jclouds.blobstore.domain.Key; +import org.jclouds.blobstore.util.BlobStoreUtils; import org.jclouds.http.HttpRequest; import org.jclouds.http.MultipartForm; import org.jclouds.http.MultipartForm.Part; -import org.jclouds.mezeo.pcs2.functions.Key; -import org.jclouds.mezeo.pcs2.util.PCSUtils; -import org.jclouds.rest.binders.EntityBinder; +import org.jclouds.rest.decorators.RequestDecorator; import com.google.common.collect.ImmutableMultimap; import com.google.common.collect.Multimap; @@ -46,13 +46,13 @@ import com.google.common.collect.Multimap; * * @author Adrian Cole */ -public class PCSFileAsMultipartFormBinder implements EntityBinder { +public class AddBlobEntityAsMultipartForm implements RequestDecorator { - public static final String BOUNDARY = "--PCS--"; + public static final String BOUNDARY = "--JCLOUDS--"; - public void addEntityToRequest(Object entity, HttpRequest request) { + public HttpRequest decorateRequest(HttpRequest request, Object entity) { Blob object = (Blob) entity; - Key key = PCSUtils.parseKey(new Key("junk", object.getKey())); + Key key = BlobStoreUtils.parseKey(new Key("junk", object.getKey())); Multimap partHeaders = ImmutableMultimap.of("Content-Disposition", String .format("form-data; name=\"%s\"; filename=\"%s\"", key.getKey(), key.getKey()), HttpHeaders.CONTENT_TYPE, checkNotNull(object.getMetadata().getContentType(), @@ -84,6 +84,6 @@ public class PCSFileAsMultipartFormBinder implements EntityBinder { "multipart/form-data; boundary=" + BOUNDARY); request.getHeaders().put(HttpHeaders.CONTENT_LENGTH, form.getSize() + ""); - + return request; } } diff --git a/blobstore/core/src/main/java/org/jclouds/blobstore/binders/UserMetadataBinder.java b/blobstore/core/src/main/java/org/jclouds/blobstore/decorators/AddHeadersWithPrefix.java similarity index 84% rename from blobstore/core/src/main/java/org/jclouds/blobstore/binders/UserMetadataBinder.java rename to blobstore/core/src/main/java/org/jclouds/blobstore/decorators/AddHeadersWithPrefix.java index 5e8fc6f91c..1fc39f01a1 100644 --- a/blobstore/core/src/main/java/org/jclouds/blobstore/binders/UserMetadataBinder.java +++ b/blobstore/core/src/main/java/org/jclouds/blobstore/decorators/AddHeadersWithPrefix.java @@ -21,7 +21,7 @@ * under the License. * ==================================================================== */ -package org.jclouds.blobstore.binders; +package org.jclouds.blobstore.decorators; import static org.jclouds.blobstore.reference.BlobStoreConstants.PROPERTY_USER_METADATA_PREFIX; @@ -31,20 +31,20 @@ import javax.inject.Inject; import javax.inject.Named; import org.jclouds.http.HttpRequest; -import org.jclouds.rest.binders.EntityBinder; +import org.jclouds.rest.decorators.RequestDecorator; import com.google.common.collect.Multimap; -public class UserMetadataBinder implements EntityBinder { +public class AddHeadersWithPrefix implements RequestDecorator { private final String metadataPrefix; @Inject - public UserMetadataBinder(@Named(PROPERTY_USER_METADATA_PREFIX) String metadataPrefix) { + public AddHeadersWithPrefix(@Named(PROPERTY_USER_METADATA_PREFIX) String metadataPrefix) { this.metadataPrefix = metadataPrefix; } @SuppressWarnings("unchecked") - public void addEntityToRequest(Object entity, HttpRequest request) { + public HttpRequest decorateRequest( HttpRequest request, Object entity) { Multimap userMetadata = (Multimap) entity; for (Entry entry : userMetadata.entries()) { if (entry.getKey().startsWith(metadataPrefix)) { @@ -54,6 +54,7 @@ public class UserMetadataBinder implements EntityBinder { entry.getValue()); } } + return request; } } diff --git a/mezeo/pcs2/core/src/main/java/org/jclouds/mezeo/pcs2/functions/Key.java b/blobstore/core/src/main/java/org/jclouds/blobstore/domain/Key.java similarity index 98% rename from mezeo/pcs2/core/src/main/java/org/jclouds/mezeo/pcs2/functions/Key.java rename to blobstore/core/src/main/java/org/jclouds/blobstore/domain/Key.java index 3e49cf36c9..e378235da6 100644 --- a/mezeo/pcs2/core/src/main/java/org/jclouds/mezeo/pcs2/functions/Key.java +++ b/blobstore/core/src/main/java/org/jclouds/blobstore/domain/Key.java @@ -21,7 +21,7 @@ * under the License. * ==================================================================== */ -package org.jclouds.mezeo.pcs2.functions; +package org.jclouds.blobstore.domain; public class Key { private final String container; diff --git a/blobstore/core/src/main/java/org/jclouds/blobstore/functions/ClearAndDeleteIfNotEmpty.java b/blobstore/core/src/main/java/org/jclouds/blobstore/functions/ClearAndDeleteIfNotEmpty.java index 2a96bc7d33..fe807ca467 100644 --- a/blobstore/core/src/main/java/org/jclouds/blobstore/functions/ClearAndDeleteIfNotEmpty.java +++ b/blobstore/core/src/main/java/org/jclouds/blobstore/functions/ClearAndDeleteIfNotEmpty.java @@ -38,13 +38,13 @@ import org.jclouds.blobstore.reference.BlobStoreConstants; import org.jclouds.blobstore.strategy.ClearContainerStrategy; import org.jclouds.http.HttpRequest; import org.jclouds.http.HttpResponseException; -import org.jclouds.rest.RestContext; +import org.jclouds.rest.InvocationContext; import org.jclouds.util.Utils; import com.google.common.base.Function; public class ClearAndDeleteIfNotEmpty> - implements Function, RestContext { + implements Function, InvocationContext { static final Void v; static { Constructor cv; diff --git a/blobstore/core/src/main/java/org/jclouds/blobstore/functions/ParseBlobFromHeadersAndHttpContent.java b/blobstore/core/src/main/java/org/jclouds/blobstore/functions/ParseBlobFromHeadersAndHttpContent.java index 9febbf5ef8..ec178c172e 100644 --- a/blobstore/core/src/main/java/org/jclouds/blobstore/functions/ParseBlobFromHeadersAndHttpContent.java +++ b/blobstore/core/src/main/java/org/jclouds/blobstore/functions/ParseBlobFromHeadersAndHttpContent.java @@ -32,7 +32,7 @@ import org.jclouds.blobstore.domain.BlobMetadata; import org.jclouds.http.HttpException; import org.jclouds.http.HttpRequest; import org.jclouds.http.HttpResponse; -import org.jclouds.rest.RestContext; +import org.jclouds.rest.InvocationContext; import com.google.common.annotations.VisibleForTesting; import com.google.common.base.Function; @@ -44,7 +44,7 @@ import com.google.common.base.Function; * @author Adrian Cole */ public class ParseBlobFromHeadersAndHttpContent> - implements Function, RestContext { + implements Function, InvocationContext { private final ParseContentTypeFromHeaders metadataParser; private final Provider blobFactory; diff --git a/blobstore/core/src/main/java/org/jclouds/blobstore/functions/ParseContentTypeFromHeaders.java b/blobstore/core/src/main/java/org/jclouds/blobstore/functions/ParseContentTypeFromHeaders.java index 919bc5eb48..99dd775485 100644 --- a/blobstore/core/src/main/java/org/jclouds/blobstore/functions/ParseContentTypeFromHeaders.java +++ b/blobstore/core/src/main/java/org/jclouds/blobstore/functions/ParseContentTypeFromHeaders.java @@ -31,7 +31,7 @@ import org.jclouds.blobstore.domain.BlobMetadata; import org.jclouds.http.HttpException; import org.jclouds.http.HttpRequest; import org.jclouds.http.HttpResponse; -import org.jclouds.rest.RestContext; +import org.jclouds.rest.InvocationContext; import com.google.common.annotations.VisibleForTesting; import com.google.common.base.Function; @@ -40,7 +40,7 @@ import com.google.common.base.Function; * @author Adrian Cole */ public class ParseContentTypeFromHeaders implements - Function, RestContext { + Function, InvocationContext { private final Provider metadataFactory; private HttpRequest request; private Object[] args; diff --git a/blobstore/core/src/main/java/org/jclouds/blobstore/internal/BaseBlobMap.java b/blobstore/core/src/main/java/org/jclouds/blobstore/internal/BaseBlobMap.java index 8c4e5c7b9a..94c1cbe92b 100755 --- a/blobstore/core/src/main/java/org/jclouds/blobstore/internal/BaseBlobMap.java +++ b/blobstore/core/src/main/java/org/jclouds/blobstore/internal/BaseBlobMap.java @@ -44,7 +44,7 @@ import org.jclouds.blobstore.strategy.ContainerCountStrategy; import org.jclouds.blobstore.strategy.ContainsValueStrategy; import org.jclouds.blobstore.strategy.GetAllBlobMetadataStrategy; import org.jclouds.blobstore.strategy.GetAllBlobsStrategy; -import org.jclouds.rest.BoundedSortedSet; +import org.jclouds.rest.internal.BoundedSortedSet; import org.jclouds.util.Utils; import com.google.common.collect.Sets; diff --git a/blobstore/core/src/main/java/org/jclouds/blobstore/util/BlobStoreUtils.java b/blobstore/core/src/main/java/org/jclouds/blobstore/util/BlobStoreUtils.java index 2219ce10fb..3c4f81a53c 100644 --- a/blobstore/core/src/main/java/org/jclouds/blobstore/util/BlobStoreUtils.java +++ b/blobstore/core/src/main/java/org/jclouds/blobstore/util/BlobStoreUtils.java @@ -30,6 +30,7 @@ import java.io.InputStream; import org.jclouds.blobstore.domain.Blob; import org.jclouds.blobstore.domain.BlobMetadata; +import org.jclouds.blobstore.domain.Key; import org.jclouds.util.Utils; /** @@ -39,6 +40,17 @@ import org.jclouds.util.Utils; */ public class BlobStoreUtils { + public static Key parseKey(Key key) { + + if (key.getKey().indexOf('/') != -1) { + String container = key.getContainer() + '/' + + key.getKey().substring(0, key.getKey().lastIndexOf('/')); + String newKey = key.getKey().substring(key.getKey().lastIndexOf('/') + 1); + key = new Key(container.replaceAll("//", "/"), newKey); + } + return key; + } + public static String getContentAsStringAndClose(Blob object) throws IOException { checkNotNull(object, "s3Object"); diff --git a/mezeo/pcs2/core/src/test/java/org/jclouds/mezeo/pcs2/binders/PCSFileAsMultipartFormBinderTest.java b/blobstore/core/src/test/java/org/jclouds/blobstore/decorators/AddBlobEntityAsMultipartFormTest.java similarity index 79% rename from mezeo/pcs2/core/src/test/java/org/jclouds/mezeo/pcs2/binders/PCSFileAsMultipartFormBinderTest.java rename to blobstore/core/src/test/java/org/jclouds/blobstore/decorators/AddBlobEntityAsMultipartFormTest.java index bd93404a7f..f6a0e575ad 100644 --- a/mezeo/pcs2/core/src/test/java/org/jclouds/mezeo/pcs2/binders/PCSFileAsMultipartFormBinderTest.java +++ b/blobstore/core/src/test/java/org/jclouds/blobstore/decorators/AddBlobEntityAsMultipartFormTest.java @@ -21,7 +21,7 @@ * under the License. * ==================================================================== */ -package org.jclouds.mezeo.pcs2.binders; +package org.jclouds.blobstore.decorators; import static org.testng.Assert.assertEquals; @@ -32,8 +32,10 @@ import java.net.URI; import javax.ws.rs.core.HttpHeaders; import javax.ws.rs.core.MediaType; +import org.jclouds.blobstore.decorators.AddBlobEntityAsMultipartForm; +import org.jclouds.blobstore.domain.Blob; +import org.jclouds.blobstore.domain.BlobMetadata; import org.jclouds.http.HttpRequest; -import org.jclouds.mezeo.pcs2.domain.PCSFile; import org.jclouds.util.Utils; import org.testng.annotations.Test; @@ -42,34 +44,34 @@ import org.testng.annotations.Test; * * @author Adrian Cole */ -@Test(testName = "pcs2.PCSFileAsMultipartFormBinderTest") -public class PCSFileAsMultipartFormBinderTest { +@Test(testName = "blobstore.AddBlobEntityAsMultipartFormTest") +public class AddBlobEntityAsMultipartFormTest { - public static String BOUNDRY = PCSFileAsMultipartFormBinder.BOUNDARY; + public static String BOUNDRY = AddBlobEntityAsMultipartForm.BOUNDARY; public static final String EXPECTS; - public static final PCSFile TEST_BLOB; + public static final Blob TEST_BLOB; static { StringBuilder builder = new StringBuilder("--"); addData(BOUNDRY, "hello", builder); builder.append("--").append(BOUNDRY).append("--").append("\r\n"); EXPECTS = builder.toString(); - TEST_BLOB = new PCSFile("hello"); + TEST_BLOB = new Blob("hello"); TEST_BLOB.setData("hello"); TEST_BLOB.getMetadata().setContentType(MediaType.TEXT_PLAIN); } public void testSinglePart() throws IOException { - assertEquals(EXPECTS.length(), 123); + assertEquals(EXPECTS.length(), 131); - PCSFileAsMultipartFormBinder binder = new PCSFileAsMultipartFormBinder(); + AddBlobEntityAsMultipartForm binder = new AddBlobEntityAsMultipartForm(); HttpRequest request = new HttpRequest("GET", URI.create("http://localhost:8001")); - binder.addEntityToRequest(TEST_BLOB, request); + binder.decorateRequest(request, TEST_BLOB); assertEquals(Utils.toStringAndClose((InputStream) request.getEntity()), EXPECTS); - assertEquals(request.getFirstHeaderOrNull(HttpHeaders.CONTENT_LENGTH), 123 + ""); + assertEquals(request.getFirstHeaderOrNull(HttpHeaders.CONTENT_LENGTH), 131 + ""); assertEquals(request.getFirstHeaderOrNull(HttpHeaders.CONTENT_TYPE), "multipart/form-data; boundary=" + BOUNDRY); diff --git a/blobstore/core/src/test/java/org/jclouds/blobstore/util/BlobStoreUtilsTest.java b/blobstore/core/src/test/java/org/jclouds/blobstore/util/BlobStoreUtilsTest.java new file mode 100644 index 0000000000..21828ad328 --- /dev/null +++ b/blobstore/core/src/test/java/org/jclouds/blobstore/util/BlobStoreUtilsTest.java @@ -0,0 +1,28 @@ +package org.jclouds.blobstore.util; + +import static org.testng.Assert.assertEquals; + +import org.jclouds.blobstore.domain.Key; +import org.testng.annotations.Test; + +/** + * Tests behavior of {@code BlobStoreUtils} + * + * @author Adrian Cole + */ +@Test(groups = "unit", testName = "blobstore.BlobStoreUtilsTest") +public class BlobStoreUtilsTest { + + public void testParseKey() { + Key key = BlobStoreUtils.parseKey(new Key("container", "key")); + assertEquals(key.getContainer(), "container"); + assertEquals(key.getKey(), "key"); + key = BlobStoreUtils.parseKey(new Key("container", "container/key")); + assertEquals(key.getContainer(), "container/container"); + assertEquals(key.getKey(), "key"); + key = BlobStoreUtils.parseKey(new Key("container", "/container/key")); + assertEquals(key.getContainer(), "container/container"); + assertEquals(key.getKey(), "key"); + + } +} diff --git a/core/src/main/java/org/jclouds/cloud/CloudContextBuilder.java b/core/src/main/java/org/jclouds/cloud/CloudContextBuilder.java index e7e801b833..ab94c74206 100644 --- a/core/src/main/java/org/jclouds/cloud/CloudContextBuilder.java +++ b/core/src/main/java/org/jclouds/cloud/CloudContextBuilder.java @@ -52,7 +52,7 @@ import org.jclouds.http.config.ConfiguresHttpCommandExecutorService; import org.jclouds.http.config.JavaUrlHttpCommandExecutorServiceModule; import org.jclouds.logging.config.LoggingModule; import org.jclouds.logging.jdk.config.JDKLoggingModule; -import org.jclouds.rest.config.JaxrsModule; +import org.jclouds.rest.config.RestModule; import org.jclouds.util.Jsr330; import com.google.common.annotations.VisibleForTesting; @@ -218,7 +218,7 @@ public abstract class CloudContextBuilder { } })) { - modules.add(new JaxrsModule()); + modules.add(new RestModule()); } } diff --git a/core/src/main/java/org/jclouds/http/functions/ParseContentMD5FromHeaders.java b/core/src/main/java/org/jclouds/http/functions/ParseContentMD5FromHeaders.java index a623716cc0..eac607e7b3 100644 --- a/core/src/main/java/org/jclouds/http/functions/ParseContentMD5FromHeaders.java +++ b/core/src/main/java/org/jclouds/http/functions/ParseContentMD5FromHeaders.java @@ -30,14 +30,14 @@ import org.jclouds.http.HttpRequest; import org.jclouds.http.HttpResponse; import org.jclouds.http.HttpUtils; import org.jclouds.logging.Logger; -import org.jclouds.rest.RestContext; +import org.jclouds.rest.InvocationContext; import com.google.common.base.Function; /** * @author Adrian Cole */ -public class ParseContentMD5FromHeaders implements Function, RestContext { +public class ParseContentMD5FromHeaders implements Function, InvocationContext { public static class NoContentMD5Exception extends RuntimeException { diff --git a/core/src/main/java/org/jclouds/http/internal/BaseHttpCommandExecutorService.java b/core/src/main/java/org/jclouds/http/internal/BaseHttpCommandExecutorService.java index 7e45a7cc7d..d3a1924691 100644 --- a/core/src/main/java/org/jclouds/http/internal/BaseHttpCommandExecutorService.java +++ b/core/src/main/java/org/jclouds/http/internal/BaseHttpCommandExecutorService.java @@ -75,7 +75,7 @@ public abstract class BaseHttpCommandExecutorService implements HttpCommandEx try { logger.trace("%s - filtering request %s", request.getEndpoint(), request); for (HttpRequestFilter filter : request.getFilters()) { - filter.filter(request); + request = filter.filter(request); } logger.trace("%s - request now %s", request.getEndpoint(), request); nativeRequest = convert(request); diff --git a/core/src/main/java/org/jclouds/rest/RestContext.java b/core/src/main/java/org/jclouds/rest/InvocationContext.java similarity index 97% rename from core/src/main/java/org/jclouds/rest/RestContext.java rename to core/src/main/java/org/jclouds/rest/InvocationContext.java index 28c829ddc3..b015c239df 100644 --- a/core/src/main/java/org/jclouds/rest/RestContext.java +++ b/core/src/main/java/org/jclouds/rest/InvocationContext.java @@ -34,7 +34,7 @@ import org.jclouds.http.HttpRequest; * @see PathParam * @author Adrian Cole */ -public interface RestContext { +public interface InvocationContext { void setContext(HttpRequest request, Object[] args); Object[] getArgs(); diff --git a/core/src/main/java/org/jclouds/rest/RestClientFactory.java b/core/src/main/java/org/jclouds/rest/RestClientFactory.java index 16c6b017ea..8a81f0c33f 100644 --- a/core/src/main/java/org/jclouds/rest/RestClientFactory.java +++ b/core/src/main/java/org/jclouds/rest/RestClientFactory.java @@ -28,6 +28,8 @@ import java.lang.reflect.Proxy; import javax.inject.Inject; +import org.jclouds.rest.internal.RestClientProxy; + import com.google.inject.Injector; import com.google.inject.Key; import com.google.inject.TypeLiteral; diff --git a/core/src/main/java/org/jclouds/rest/EntityParam.java b/core/src/main/java/org/jclouds/rest/annotations/DecoratorParam.java old mode 100644 new mode 100755 similarity index 81% rename from core/src/main/java/org/jclouds/rest/EntityParam.java rename to core/src/main/java/org/jclouds/rest/annotations/DecoratorParam.java index c1f394988e..a382811ce2 --- a/core/src/main/java/org/jclouds/rest/EntityParam.java +++ b/core/src/main/java/org/jclouds/rest/annotations/DecoratorParam.java @@ -21,7 +21,7 @@ * under the License. * ==================================================================== */ -package org.jclouds.rest; +package org.jclouds.rest.annotations; import static java.lang.annotation.ElementType.PARAMETER; import static java.lang.annotation.RetentionPolicy.RUNTIME; @@ -29,20 +29,20 @@ import static java.lang.annotation.RetentionPolicy.RUNTIME; import java.lang.annotation.Retention; import java.lang.annotation.Target; -import org.jclouds.rest.binders.EntityBinder; -import org.jclouds.rest.binders.ToStringEntityBinder; +import org.jclouds.rest.decorators.RequestDecorator; /** - * Designates that this parameter will hold the entity for a PUT or POST command. + * Designates that this parameter will modify the request, possibly including adding an entity to + * it. * * @author Adrian Cole */ @Target(PARAMETER) @Retention(RUNTIME) -public @interface EntityParam { +public @interface DecoratorParam { /** * how to persist this entity. */ - Class value() default ToStringEntityBinder.class; + Class value(); } diff --git a/core/src/main/java/org/jclouds/rest/Endpoint.java b/core/src/main/java/org/jclouds/rest/annotations/Endpoint.java similarity index 97% rename from core/src/main/java/org/jclouds/rest/Endpoint.java rename to core/src/main/java/org/jclouds/rest/annotations/Endpoint.java index 71d774201d..0c00d03cda 100644 --- a/core/src/main/java/org/jclouds/rest/Endpoint.java +++ b/core/src/main/java/org/jclouds/rest/annotations/Endpoint.java @@ -21,7 +21,7 @@ * under the License. * ==================================================================== */ -package org.jclouds.rest; +package org.jclouds.rest.annotations; import static java.lang.annotation.ElementType.METHOD; import static java.lang.annotation.ElementType.PARAMETER; diff --git a/core/src/main/java/org/jclouds/rest/ExceptionParser.java b/core/src/main/java/org/jclouds/rest/annotations/ExceptionParser.java old mode 100644 new mode 100755 similarity index 97% rename from core/src/main/java/org/jclouds/rest/ExceptionParser.java rename to core/src/main/java/org/jclouds/rest/annotations/ExceptionParser.java index f4abbe3590..619084b754 --- a/core/src/main/java/org/jclouds/rest/ExceptionParser.java +++ b/core/src/main/java/org/jclouds/rest/annotations/ExceptionParser.java @@ -21,7 +21,7 @@ * under the License. * ==================================================================== */ -package org.jclouds.rest; +package org.jclouds.rest.annotations; import static java.lang.annotation.ElementType.METHOD; import static java.lang.annotation.RetentionPolicy.RUNTIME; diff --git a/core/src/main/java/org/jclouds/rest/Headers.java b/core/src/main/java/org/jclouds/rest/annotations/Headers.java similarity index 98% rename from core/src/main/java/org/jclouds/rest/Headers.java rename to core/src/main/java/org/jclouds/rest/annotations/Headers.java index d2429cf192..a0c2cfdbd0 100755 --- a/core/src/main/java/org/jclouds/rest/Headers.java +++ b/core/src/main/java/org/jclouds/rest/annotations/Headers.java @@ -21,7 +21,7 @@ * under the License. * ==================================================================== */ -package org.jclouds.rest; +package org.jclouds.rest.annotations; import static java.lang.annotation.ElementType.METHOD; import static java.lang.annotation.ElementType.TYPE; diff --git a/core/src/main/java/org/jclouds/rest/HostPrefixParam.java b/core/src/main/java/org/jclouds/rest/annotations/HostPrefixParam.java old mode 100644 new mode 100755 similarity index 98% rename from core/src/main/java/org/jclouds/rest/HostPrefixParam.java rename to core/src/main/java/org/jclouds/rest/annotations/HostPrefixParam.java index 751abfbde5..6dec545fed --- a/core/src/main/java/org/jclouds/rest/HostPrefixParam.java +++ b/core/src/main/java/org/jclouds/rest/annotations/HostPrefixParam.java @@ -21,7 +21,7 @@ * under the License. * ==================================================================== */ -package org.jclouds.rest; +package org.jclouds.rest.annotations; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; diff --git a/core/src/main/java/org/jclouds/rest/MapBinder.java b/core/src/main/java/org/jclouds/rest/annotations/MapBinder.java similarity index 89% rename from core/src/main/java/org/jclouds/rest/MapBinder.java rename to core/src/main/java/org/jclouds/rest/annotations/MapBinder.java index cfaf18c30e..4919b93a51 100644 --- a/core/src/main/java/org/jclouds/rest/MapBinder.java +++ b/core/src/main/java/org/jclouds/rest/annotations/MapBinder.java @@ -21,7 +21,7 @@ * under the License. * ==================================================================== */ -package org.jclouds.rest; +package org.jclouds.rest.annotations; import static java.lang.annotation.ElementType.METHOD; import static java.lang.annotation.RetentionPolicy.RUNTIME; @@ -29,7 +29,7 @@ import static java.lang.annotation.RetentionPolicy.RUNTIME; import java.lang.annotation.Retention; import java.lang.annotation.Target; -import org.jclouds.rest.binders.MapEntityBinder; +import org.jclouds.rest.decorators.MapRequestDecorator; /** * Designates that this parameter will hold the entity for a PUT or POST command. @@ -41,8 +41,8 @@ import org.jclouds.rest.binders.MapEntityBinder; public @interface MapBinder { /** - * How to bind {@link MapEntityParam} values, if there is no {@link MapEntityBinder} in the method + * How to bind {@link MapEntityParam} values, if there is no {@link MapRequestDecorator} in the method * definition */ - Class value(); + Class value(); } diff --git a/core/src/main/java/org/jclouds/rest/MapEntityParam.java b/core/src/main/java/org/jclouds/rest/annotations/MapEntityParam.java similarity index 91% rename from core/src/main/java/org/jclouds/rest/MapEntityParam.java rename to core/src/main/java/org/jclouds/rest/annotations/MapEntityParam.java index 2e4e0e56c1..2b0b5e2363 100644 --- a/core/src/main/java/org/jclouds/rest/MapEntityParam.java +++ b/core/src/main/java/org/jclouds/rest/annotations/MapEntityParam.java @@ -21,7 +21,7 @@ * under the License. * ==================================================================== */ -package org.jclouds.rest; +package org.jclouds.rest.annotations; import static java.lang.annotation.ElementType.PARAMETER; import static java.lang.annotation.RetentionPolicy.RUNTIME; @@ -39,7 +39,7 @@ import java.lang.annotation.Target; public @interface MapEntityParam { /** - * The key used in a map passed to the {@link MapEntityBinder} associated with the request. + * The key used in a map passed to the {@link MapRequestDecorator} associated with the request. */ String value(); } diff --git a/core/src/main/java/org/jclouds/rest/annotations/MatrixParams.java b/core/src/main/java/org/jclouds/rest/annotations/MatrixParams.java new file mode 100644 index 0000000000..b2ce8bbd3d --- /dev/null +++ b/core/src/main/java/org/jclouds/rest/annotations/MatrixParams.java @@ -0,0 +1,50 @@ +/** + * + * Copyright (C) 2009 Global Cloud Specialists, Inc. + * + * ==================================================================== + * 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.rest.annotations; + +import static java.lang.annotation.ElementType.METHOD; +import static java.lang.annotation.ElementType.TYPE; +import static java.lang.annotation.RetentionPolicy.RUNTIME; + +import java.lang.annotation.Retention; +import java.lang.annotation.Target; + +import javax.ws.rs.MatrixParam; + +/** + * Designates that a matrix param will be added to the request. + * + * @see MatrixParam + * @author Adrian Cole + */ +@Target( { TYPE, METHOD }) +@Retention(RUNTIME) +public @interface MatrixParams { + + public static final String NULL = "MATRIX_NULL"; + + String[] keys(); + + String[] values() default NULL; +} diff --git a/core/src/main/java/org/jclouds/rest/ParamParser.java b/core/src/main/java/org/jclouds/rest/annotations/ParamParser.java similarity index 97% rename from core/src/main/java/org/jclouds/rest/ParamParser.java rename to core/src/main/java/org/jclouds/rest/annotations/ParamParser.java index eb3b9b7d61..8d84c4c37a 100755 --- a/core/src/main/java/org/jclouds/rest/ParamParser.java +++ b/core/src/main/java/org/jclouds/rest/annotations/ParamParser.java @@ -21,7 +21,7 @@ * under the License. * ==================================================================== */ -package org.jclouds.rest; +package org.jclouds.rest.annotations; import static java.lang.annotation.ElementType.METHOD; import static java.lang.annotation.ElementType.PARAMETER; diff --git a/core/src/main/java/org/jclouds/rest/QueryParams.java b/core/src/main/java/org/jclouds/rest/annotations/QueryParams.java similarity index 97% rename from core/src/main/java/org/jclouds/rest/QueryParams.java rename to core/src/main/java/org/jclouds/rest/annotations/QueryParams.java index 92731b1936..b45a46bf99 100755 --- a/core/src/main/java/org/jclouds/rest/QueryParams.java +++ b/core/src/main/java/org/jclouds/rest/annotations/QueryParams.java @@ -21,7 +21,7 @@ * under the License. * ==================================================================== */ -package org.jclouds.rest; +package org.jclouds.rest.annotations; import static java.lang.annotation.ElementType.*; import static java.lang.annotation.RetentionPolicy.RUNTIME; diff --git a/core/src/main/java/org/jclouds/rest/RequestFilters.java b/core/src/main/java/org/jclouds/rest/annotations/RequestFilters.java old mode 100644 new mode 100755 similarity index 97% rename from core/src/main/java/org/jclouds/rest/RequestFilters.java rename to core/src/main/java/org/jclouds/rest/annotations/RequestFilters.java index 9b5a4da4d2..c28cb482ce --- a/core/src/main/java/org/jclouds/rest/RequestFilters.java +++ b/core/src/main/java/org/jclouds/rest/annotations/RequestFilters.java @@ -21,7 +21,7 @@ * under the License. * ==================================================================== */ -package org.jclouds.rest; +package org.jclouds.rest.annotations; import static java.lang.annotation.ElementType.METHOD; import static java.lang.annotation.ElementType.TYPE; diff --git a/core/src/main/java/org/jclouds/rest/ResponseParser.java b/core/src/main/java/org/jclouds/rest/annotations/ResponseParser.java old mode 100644 new mode 100755 similarity index 97% rename from core/src/main/java/org/jclouds/rest/ResponseParser.java rename to core/src/main/java/org/jclouds/rest/annotations/ResponseParser.java index bed5c97fc9..c961519fca --- a/core/src/main/java/org/jclouds/rest/ResponseParser.java +++ b/core/src/main/java/org/jclouds/rest/annotations/ResponseParser.java @@ -21,7 +21,7 @@ * under the License. * ==================================================================== */ -package org.jclouds.rest; +package org.jclouds.rest.annotations; import static java.lang.annotation.ElementType.METHOD; import static java.lang.annotation.RetentionPolicy.RUNTIME; diff --git a/core/src/main/java/org/jclouds/rest/SkipEncoding.java b/core/src/main/java/org/jclouds/rest/annotations/SkipEncoding.java old mode 100644 new mode 100755 similarity index 97% rename from core/src/main/java/org/jclouds/rest/SkipEncoding.java rename to core/src/main/java/org/jclouds/rest/annotations/SkipEncoding.java index 4da909f3ea..20aa5aff3a --- a/core/src/main/java/org/jclouds/rest/SkipEncoding.java +++ b/core/src/main/java/org/jclouds/rest/annotations/SkipEncoding.java @@ -21,7 +21,7 @@ * under the License. * ==================================================================== */ -package org.jclouds.rest; +package org.jclouds.rest.annotations; import static java.lang.annotation.ElementType.TYPE; import static java.lang.annotation.RetentionPolicy.RUNTIME; diff --git a/core/src/main/java/org/jclouds/rest/VirtualHost.java b/core/src/main/java/org/jclouds/rest/annotations/VirtualHost.java old mode 100644 new mode 100755 similarity index 97% rename from core/src/main/java/org/jclouds/rest/VirtualHost.java rename to core/src/main/java/org/jclouds/rest/annotations/VirtualHost.java index 7ddcc6e675..7dd60da435 --- a/core/src/main/java/org/jclouds/rest/VirtualHost.java +++ b/core/src/main/java/org/jclouds/rest/annotations/VirtualHost.java @@ -21,7 +21,7 @@ * under the License. * ==================================================================== */ -package org.jclouds.rest; +package org.jclouds.rest.annotations; import static java.lang.annotation.ElementType.TYPE; import static java.lang.annotation.ElementType.METHOD; diff --git a/core/src/main/java/org/jclouds/rest/XMLResponseParser.java b/core/src/main/java/org/jclouds/rest/annotations/XMLResponseParser.java old mode 100644 new mode 100755 similarity index 97% rename from core/src/main/java/org/jclouds/rest/XMLResponseParser.java rename to core/src/main/java/org/jclouds/rest/annotations/XMLResponseParser.java index 81a305f39f..5f4670120d --- a/core/src/main/java/org/jclouds/rest/XMLResponseParser.java +++ b/core/src/main/java/org/jclouds/rest/annotations/XMLResponseParser.java @@ -21,7 +21,7 @@ * under the License. * ==================================================================== */ -package org.jclouds.rest; +package org.jclouds.rest.annotations; import static java.lang.annotation.ElementType.METHOD; import static java.lang.annotation.RetentionPolicy.RUNTIME; diff --git a/core/src/main/java/org/jclouds/rest/binders/HttpRequestOptionsBinder.java b/core/src/main/java/org/jclouds/rest/binders/HttpRequestOptionsBinder.java deleted file mode 100755 index dc3f23bd9b..0000000000 --- a/core/src/main/java/org/jclouds/rest/binders/HttpRequestOptionsBinder.java +++ /dev/null @@ -1,49 +0,0 @@ -/** - * - * Copyright (C) 2009 Global Cloud Specialists, Inc. - * - * ==================================================================== - * 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.rest.binders; - -import javax.ws.rs.core.HttpHeaders; - -import org.jclouds.http.HttpRequest; -import org.jclouds.http.options.HttpRequestOptions; - -import javax.inject.Singleton; - -/** - * Adds an entity to a request. - * - * @author Adrian Cole - */ -@Singleton -public class HttpRequestOptionsBinder implements EntityBinder { - public void addEntityToRequest(Object entity, HttpRequest request) { - HttpRequestOptions options = (HttpRequestOptions) entity; - String stringEntity = options.buildStringEntity(); - if (stringEntity != null) { - request.getHeaders().put(HttpHeaders.CONTENT_TYPE, "application/unknown"); - request.getHeaders().put(HttpHeaders.CONTENT_LENGTH, stringEntity.getBytes().length + ""); - request.setEntity(stringEntity); - } - } -} diff --git a/core/src/main/java/org/jclouds/rest/config/JaxrsModule.java b/core/src/main/java/org/jclouds/rest/config/RestModule.java old mode 100644 new mode 100755 similarity index 95% rename from core/src/main/java/org/jclouds/rest/config/JaxrsModule.java rename to core/src/main/java/org/jclouds/rest/config/RestModule.java index e042dc8590..b86dd23a69 --- a/core/src/main/java/org/jclouds/rest/config/JaxrsModule.java +++ b/core/src/main/java/org/jclouds/rest/config/RestModule.java @@ -28,7 +28,7 @@ import javax.ws.rs.ext.RuntimeDelegate; import org.jclouds.http.TransformingHttpCommand; import org.jclouds.http.TransformingHttpCommandImpl; import org.jclouds.http.functions.config.ParserModule; -import org.jclouds.rest.RuntimeDelegateImpl; +import org.jclouds.rest.internal.RuntimeDelegateImpl; import com.google.inject.AbstractModule; import com.google.inject.TypeLiteral; @@ -38,7 +38,7 @@ import com.google.inject.assistedinject.FactoryProvider; * * @author Adrian Cole */ -public class JaxrsModule extends AbstractModule { +public class RestModule extends AbstractModule { private final static TypeLiteral httpCommandFactoryLiteral = new TypeLiteral() { }; diff --git a/core/src/main/java/org/jclouds/rest/binders/JsonBinder.java b/core/src/main/java/org/jclouds/rest/decorators/AddAsJsonEntity.java similarity index 84% rename from core/src/main/java/org/jclouds/rest/binders/JsonBinder.java rename to core/src/main/java/org/jclouds/rest/decorators/AddAsJsonEntity.java index 7091dd394d..13db1f4d51 100644 --- a/core/src/main/java/org/jclouds/rest/binders/JsonBinder.java +++ b/core/src/main/java/org/jclouds/rest/decorators/AddAsJsonEntity.java @@ -21,7 +21,7 @@ * under the License. * ==================================================================== */ -package org.jclouds.rest.binders; +package org.jclouds.rest.decorators; import static com.google.common.base.Preconditions.checkState; @@ -42,16 +42,16 @@ import com.google.gson.Gson; * @author Adrian Cole * @since 4.0 */ -public class JsonBinder implements MapEntityBinder { +public class AddAsJsonEntity implements MapRequestDecorator { @Inject protected Gson gson; - public void addEntityToRequest(Map postParams, HttpRequest request) { - addEntityToRequest((Object) postParams, request); + public HttpRequest decorateRequest(HttpRequest request, Map postParams) { + return decorateRequest(request, (Object) postParams); } - public void addEntityToRequest(Object toBind, HttpRequest request) { + public HttpRequest decorateRequest(HttpRequest request, Object toBind) { checkState(gson != null, "Program error: gson should have been injected at this point"); String json = gson.toJson(toBind); request.setEntity(json); @@ -59,6 +59,7 @@ public class JsonBinder implements MapEntityBinder { Collections.singletonList(json.getBytes().length + "")); request.getHeaders().replaceValues(HttpHeaders.CONTENT_TYPE, Collections.singletonList(MediaType.APPLICATION_JSON)); + return request; } } \ No newline at end of file diff --git a/core/src/main/java/org/jclouds/rest/binders/ToStringEntityBinder.java b/core/src/main/java/org/jclouds/rest/decorators/AddAsStringEntity.java similarity index 80% rename from core/src/main/java/org/jclouds/rest/binders/ToStringEntityBinder.java rename to core/src/main/java/org/jclouds/rest/decorators/AddAsStringEntity.java index 9d96ae963b..3f1aea00ac 100755 --- a/core/src/main/java/org/jclouds/rest/binders/ToStringEntityBinder.java +++ b/core/src/main/java/org/jclouds/rest/decorators/AddAsStringEntity.java @@ -21,25 +21,26 @@ * under the License. * ==================================================================== */ -package org.jclouds.rest.binders; +package org.jclouds.rest.decorators; +import javax.inject.Singleton; import javax.ws.rs.core.HttpHeaders; import org.jclouds.http.HttpRequest; -import javax.inject.Singleton; - /** * Adds an entity to a request. * * @author Adrian Cole */ @Singleton -public class ToStringEntityBinder implements EntityBinder { - public void addEntityToRequest(Object entity, HttpRequest request) { +public class AddAsStringEntity implements RequestDecorator { + public HttpRequest decorateRequest(HttpRequest request, Object entity) { String stringEntity = entity.toString(); - request.getHeaders().put(HttpHeaders.CONTENT_TYPE, "application/unknown"); + if (request.getFirstHeaderOrNull(HttpHeaders.CONTENT_TYPE) == null) + request.getHeaders().put(HttpHeaders.CONTENT_TYPE, "application/unknown"); request.getHeaders().put(HttpHeaders.CONTENT_LENGTH, stringEntity.getBytes().length + ""); request.setEntity(stringEntity); + return request; } } diff --git a/core/src/main/java/org/jclouds/rest/binders/MapEntityBinder.java b/core/src/main/java/org/jclouds/rest/decorators/MapRequestDecorator.java similarity index 87% rename from core/src/main/java/org/jclouds/rest/binders/MapEntityBinder.java rename to core/src/main/java/org/jclouds/rest/decorators/MapRequestDecorator.java index 7b7904d5cc..c00b36083f 100644 --- a/core/src/main/java/org/jclouds/rest/binders/MapEntityBinder.java +++ b/core/src/main/java/org/jclouds/rest/decorators/MapRequestDecorator.java @@ -21,7 +21,7 @@ * under the License. * ==================================================================== */ -package org.jclouds.rest.binders; +package org.jclouds.rest.decorators; import java.util.Map; @@ -33,13 +33,13 @@ import org.jclouds.http.HttpRequest; * @author Adrian Cole * */ -public interface MapEntityBinder extends EntityBinder { +public interface MapRequestDecorator extends RequestDecorator { /** * creates and binds the POST entity to the request using parameters specified. * * @see MapEntityParam */ - public void addEntityToRequest(Map postParams, HttpRequest request); - + public HttpRequest decorateRequest(HttpRequest request, Map postParams); + } \ No newline at end of file diff --git a/core/src/main/java/org/jclouds/rest/binders/EntityBinder.java b/core/src/main/java/org/jclouds/rest/decorators/RequestDecorator.java similarity index 88% rename from core/src/main/java/org/jclouds/rest/binders/EntityBinder.java rename to core/src/main/java/org/jclouds/rest/decorators/RequestDecorator.java index 1523da2426..08f4b70a58 100755 --- a/core/src/main/java/org/jclouds/rest/binders/EntityBinder.java +++ b/core/src/main/java/org/jclouds/rest/decorators/RequestDecorator.java @@ -21,7 +21,7 @@ * under the License. * ==================================================================== */ -package org.jclouds.rest.binders; +package org.jclouds.rest.decorators; import org.jclouds.http.HttpRequest; @@ -30,6 +30,6 @@ import org.jclouds.http.HttpRequest; * * @author Adrian Cole */ -public interface EntityBinder { - public void addEntityToRequest(Object toBind, HttpRequest request); +public interface RequestDecorator { + public HttpRequest decorateRequest(HttpRequest request, Object input); } diff --git a/core/src/main/java/org/jclouds/rest/BoundedSortedSet.java b/core/src/main/java/org/jclouds/rest/internal/BoundedSortedSet.java similarity index 97% rename from core/src/main/java/org/jclouds/rest/BoundedSortedSet.java rename to core/src/main/java/org/jclouds/rest/internal/BoundedSortedSet.java index b34adc379f..75a53a579e 100644 --- a/core/src/main/java/org/jclouds/rest/BoundedSortedSet.java +++ b/core/src/main/java/org/jclouds/rest/internal/BoundedSortedSet.java @@ -21,7 +21,7 @@ * under the License. * ==================================================================== */ -package org.jclouds.rest; +package org.jclouds.rest.internal; import java.util.SortedSet; diff --git a/core/src/main/java/org/jclouds/rest/BoundedTreeSet.java b/core/src/main/java/org/jclouds/rest/internal/BoundedTreeSet.java similarity index 98% rename from core/src/main/java/org/jclouds/rest/BoundedTreeSet.java rename to core/src/main/java/org/jclouds/rest/internal/BoundedTreeSet.java index e686de97db..2b316fcc9a 100644 --- a/core/src/main/java/org/jclouds/rest/BoundedTreeSet.java +++ b/core/src/main/java/org/jclouds/rest/internal/BoundedTreeSet.java @@ -21,7 +21,7 @@ * under the License. * ==================================================================== */ -package org.jclouds.rest; +package org.jclouds.rest.internal; import java.util.SortedSet; import java.util.TreeSet; diff --git a/core/src/main/java/org/jclouds/rest/JaxrsAnnotationProcessor.java b/core/src/main/java/org/jclouds/rest/internal/RestAnnotationProcessor.java old mode 100644 new mode 100755 similarity index 70% rename from core/src/main/java/org/jclouds/rest/JaxrsAnnotationProcessor.java rename to core/src/main/java/org/jclouds/rest/internal/RestAnnotationProcessor.java index c7a791d510..1231ed50c4 --- a/core/src/main/java/org/jclouds/rest/JaxrsAnnotationProcessor.java +++ b/core/src/main/java/org/jclouds/rest/internal/RestAnnotationProcessor.java @@ -21,7 +21,7 @@ * under the License. * ==================================================================== */ -package org.jclouds.rest; +package org.jclouds.rest.internal; import static com.google.common.base.Preconditions.checkArgument; import static com.google.common.base.Preconditions.checkNotNull; @@ -33,7 +33,9 @@ import java.lang.annotation.Annotation; import java.lang.reflect.Method; import java.net.URI; import java.net.URLEncoder; +import java.util.Arrays; import java.util.Collection; +import java.util.Collections; import java.util.HashSet; import java.util.List; import java.util.Map; @@ -45,8 +47,11 @@ import javax.annotation.Resource; import javax.inject.Inject; import javax.inject.Named; import javax.inject.Singleton; +import javax.ws.rs.Consumes; import javax.ws.rs.HeaderParam; +import javax.ws.rs.MatrixParam; import javax.ws.rs.PathParam; +import javax.ws.rs.Produces; import javax.ws.rs.QueryParam; import javax.ws.rs.core.HttpHeaders; import javax.ws.rs.core.UriBuilder; @@ -65,9 +70,24 @@ import org.jclouds.http.functions.ReturnVoidIf2xx; import org.jclouds.http.functions.ParseSax.HandlerWithResult; import org.jclouds.http.options.HttpRequestOptions; import org.jclouds.logging.Logger; -import org.jclouds.rest.binders.EntityBinder; -import org.jclouds.rest.binders.HttpRequestOptionsBinder; -import org.jclouds.rest.binders.MapEntityBinder; +import org.jclouds.rest.InvocationContext; +import org.jclouds.rest.annotations.DecoratorParam; +import org.jclouds.rest.annotations.Endpoint; +import org.jclouds.rest.annotations.ExceptionParser; +import org.jclouds.rest.annotations.Headers; +import org.jclouds.rest.annotations.HostPrefixParam; +import org.jclouds.rest.annotations.MapBinder; +import org.jclouds.rest.annotations.MapEntityParam; +import org.jclouds.rest.annotations.MatrixParams; +import org.jclouds.rest.annotations.ParamParser; +import org.jclouds.rest.annotations.QueryParams; +import org.jclouds.rest.annotations.RequestFilters; +import org.jclouds.rest.annotations.ResponseParser; +import org.jclouds.rest.annotations.SkipEncoding; +import org.jclouds.rest.annotations.VirtualHost; +import org.jclouds.rest.annotations.XMLResponseParser; +import org.jclouds.rest.decorators.MapRequestDecorator; +import org.jclouds.rest.decorators.RequestDecorator; import com.google.common.annotations.VisibleForTesting; import com.google.common.base.Function; @@ -89,17 +109,18 @@ import com.google.inject.internal.Lists; * @author Adrian Cole */ @Singleton -public class JaxrsAnnotationProcessor { +public class RestAnnotationProcessor { @Resource protected Logger logger = Logger.NULL; private final Class declaring; - private final Map>> methodToIndexOfParamToEntityAnnotation = createMethodToIndexOfParamToAnnotation(EntityParam.class); + private final Map>> methodToIndexOfParamToDecoratorParamAnnotation = createMethodToIndexOfParamToAnnotation(DecoratorParam.class); private final Map>> methodToIndexOfParamToHeaderParamAnnotations = createMethodToIndexOfParamToAnnotation(HeaderParam.class); private final Map>> methodToIndexOfParamToHostPrefixParamAnnotations = createMethodToIndexOfParamToAnnotation(HostPrefixParam.class); private final Map>> methodToindexOfParamToEndpointAnnotations = createMethodToIndexOfParamToAnnotation(Endpoint.class); + private final Map>> methodToindexOfParamToMatrixParamAnnotations = createMethodToIndexOfParamToAnnotation(MatrixParam.class); private final Map>> methodToindexOfParamToQueryParamAnnotations = createMethodToIndexOfParamToAnnotation(QueryParam.class); private final Map>> methodToindexOfParamToPathParamAnnotations = createMethodToIndexOfParamToAnnotation(PathParam.class); private final Map>> methodToindexOfParamToPostParamAnnotations = createMethodToIndexOfParamToAnnotation(MapEntityParam.class); @@ -172,8 +193,8 @@ public class JaxrsAnnotationProcessor { } else { transformer = injector.getInstance(getParserOrThrowException(method)); } - if (transformer instanceof RestContext) { - ((RestContext) transformer).setContext(request, args); + if (transformer instanceof InvocationContext) { + ((InvocationContext) transformer).setContext(request, args); } return transformer; } @@ -189,16 +210,15 @@ public class JaxrsAnnotationProcessor { @SuppressWarnings("unchecked") @Inject - public JaxrsAnnotationProcessor(Injector injector, ParseSax.Factory parserFactory, + public RestAnnotationProcessor(Injector injector, ParseSax.Factory parserFactory, TypeLiteral typeLiteral) { this.declaring = (Class) typeLiteral.getRawType(); this.injector = injector; this.parserFactory = parserFactory; - this.optionsBinder = injector.getInstance(HttpRequestOptionsBinder.class); seedCache(declaring); } - protected Method getDelegateOrNull(Method in) { + public Method getDelegateOrNull(Method in) { return delegationMap.get(new MethodKey(in)); } @@ -208,9 +228,10 @@ public class JaxrsAnnotationProcessor { for (Method method : methods) { if (isHttpMethod(method)) { for (int index = 0; index < method.getParameterTypes().length; index++) { - methodToIndexOfParamToEntityAnnotation.get(method).get(index); + methodToIndexOfParamToDecoratorParamAnnotation.get(method).get(index); methodToIndexOfParamToHeaderParamAnnotations.get(method).get(index); methodToIndexOfParamToHostPrefixParamAnnotations.get(method).get(index); + methodToindexOfParamToMatrixParamAnnotations.get(method).get(index); methodToindexOfParamToQueryParamAnnotations.get(method).get(index); methodToindexOfParamToEndpointAnnotations.get(method).get(index); methodToindexOfParamToPathParamAnnotations.get(method).get(index); @@ -272,8 +293,6 @@ public class JaxrsAnnotationProcessor { final Injector injector; - private HttpRequestOptionsBinder optionsBinder; - public HttpRequest createRequest(Method method, Object[] args) { URI endpoint = getEndpointFor(method, args); @@ -283,68 +302,116 @@ public class JaxrsAnnotationProcessor { builder.path(declaring); builder.path(method); - if (declaring.isAnnotationPresent(QueryParams.class)) { - QueryParams query = declaring.getAnnotation(QueryParams.class); - addQuery(builder, query); + Multimap tokenValues; + if (declaring.isAnnotationPresent(SkipEncoding.class)) { + tokenValues = encodeValues(getPathParamKeyValues(method, args), declaring.getAnnotation( + SkipEncoding.class).value()); + } else { + tokenValues = encodeValues(getPathParamKeyValues(method, args)); } - if (method.isAnnotationPresent(QueryParams.class)) { - QueryParams query = method.getAnnotation(QueryParams.class); - addQuery(builder, query); - } + addQueryParams(method, args, builder, tokenValues.entries()); + addMatrixParams(method, args, builder, tokenValues.entries()); - for (Entry query : getQueryParamKeyValues(method, args).entrySet()) { - builder.queryParam(query.getKey(), query.getValue()); - } - - Multimap headers = buildHeaders(method, args); + Multimap headers = buildHeaders(method, args, tokenValues.entries()); + String stringEntity = null; HttpRequestOptions options = findOptionsIn(method, args); if (options != null) { injector.injectMembers(options);// TODO test case - headers.putAll(options.buildRequestHeaders()); + for (Entry header : options.buildRequestHeaders().entries()) { + headers.put(header.getKey(), replaceTokens(header.getValue(), tokenValues.entries())); + } for (Entry query : options.buildQueryParameters().entries()) { - builder.queryParam(query.getKey(), query.getValue()); + builder.queryParam(query.getKey(), replaceTokens(query.getValue(), tokenValues + .entries())); } for (Entry matrix : options.buildMatrixParameters().entries()) { - builder.matrixParam(matrix.getKey(), matrix.getValue()); + builder.matrixParam(matrix.getKey(), replaceTokens(matrix.getValue(), tokenValues + .entries())); } String pathSuffix = options.buildPathSuffix(); if (pathSuffix != null) { builder.path(pathSuffix); } + stringEntity = options.buildStringEntity(); + if (stringEntity != null) { + headers.put(HttpHeaders.CONTENT_LENGTH, stringEntity.getBytes().length + ""); + } } URI endPoint; try { - addHeaderIfAnnotationPresentOnMethod(headers, method, args); - if (declaring.isAnnotationPresent(SkipEncoding.class)) { - endPoint = builder.buildFromEncodedMap(getEncodedPathParamKeyValues(method, args, - declaring.getAnnotation(SkipEncoding.class).value())); - } else { - endPoint = builder.buildFromEncodedMap(getEncodedPathParamKeyValues(method, args)); - } + endPoint = builder.buildFromEncodedMap(convertUnsafe(tokenValues)); } catch (IllegalArgumentException e) { throw new IllegalStateException(e); } catch (UriBuilderException e) { throw new IllegalStateException(e); - } catch (UnsupportedEncodingException e) { - throw new IllegalStateException(e); } + HttpRequest request = new HttpRequest(httpMethod, endPoint, headers); addHostHeaderIfAnnotatedWithVirtualHost(headers, request.getEndpoint().getHost(), method); addFiltersIfAnnotated(method, request); - - buildEntityIfPostOrPutRequest(method, args, request); - return request; + if (stringEntity != null) { + request.setEntity(stringEntity); + if (headers.get(HttpHeaders.CONTENT_TYPE) != null) + headers.put(HttpHeaders.CONTENT_TYPE, "application/unknown"); + } + return decorateRequest(method, args, request); } - private void addQuery(UriBuilder builder, QueryParams query) { + private void addMatrixParams(Method method, Object[] args, UriBuilder builder, + Collection> tokenValues) { + if (declaring.isAnnotationPresent(MatrixParams.class)) { + MatrixParams query = declaring.getAnnotation(MatrixParams.class); + addMatrix(builder, query, tokenValues); + } + + if (method.isAnnotationPresent(MatrixParams.class)) { + MatrixParams query = method.getAnnotation(MatrixParams.class); + addMatrix(builder, query, tokenValues); + } + + for (Entry query : getMatrixParamKeyValues(method, args).entries()) { + builder.queryParam(query.getKey(), replaceTokens(query.getValue(), tokenValues)); + } + } + + private void addQueryParams(Method method, Object[] args, UriBuilder builder, + Collection> tokenValues) { + if (declaring.isAnnotationPresent(QueryParams.class)) { + QueryParams query = declaring.getAnnotation(QueryParams.class); + addQuery(builder, query, tokenValues); + } + + if (method.isAnnotationPresent(QueryParams.class)) { + QueryParams query = method.getAnnotation(QueryParams.class); + addQuery(builder, query, tokenValues); + } + + for (Entry query : getQueryParamKeyValues(method, args).entries()) { + builder.queryParam(query.getKey(), replaceTokens(query.getValue(), tokenValues)); + } + } + + private void addQuery(UriBuilder builder, QueryParams query, + Collection> tokenValues) { for (int i = 0; i < query.keys().length; i++) { if (query.values()[i].equals(QueryParams.NULL)) { builder.replaceQuery(query.keys()[i]); } else { - builder.queryParam(query.keys()[i], query.values()[i]); + builder.queryParam(query.keys()[i], replaceTokens(query.values()[i], tokenValues)); + } + } + } + + private void addMatrix(UriBuilder builder, MatrixParams matrix, + Collection> tokenValues) { + for (int i = 0; i < matrix.keys().length; i++) { + if (matrix.values()[i].equals(MatrixParams.NULL)) { + builder.replaceMatrix(matrix.keys()[i]); + } else { + builder.matrixParam(matrix.keys()[i], replaceTokens(matrix.values()[i], tokenValues)); } } } @@ -461,27 +528,27 @@ public class JaxrsAnnotationProcessor { return null; } - public MapEntityBinder getMapEntityBinderOrNull(Method method, Object[] args) { + public MapRequestDecorator getMapEntityBinderOrNull(Method method, Object[] args) { if (args != null) { for (Object arg : args) { if (arg instanceof Object[]) { Object[] postBinders = (Object[]) arg; if (postBinders.length == 0) { } else if (postBinders.length == 1) { - if (postBinders[0] instanceof MapEntityBinder) { - MapEntityBinder binder = (MapEntityBinder) postBinders[0]; + if (postBinders[0] instanceof MapRequestDecorator) { + MapRequestDecorator binder = (MapRequestDecorator) postBinders[0]; injector.injectMembers(binder); return binder; } } else { - if (postBinders[0] instanceof MapEntityBinder) { + if (postBinders[0] instanceof MapRequestDecorator) { throw new IllegalArgumentException( "we currently do not support multiple varargs postBinders in: " + method.getName()); } } - } else if (arg instanceof MapEntityBinder) { - MapEntityBinder binder = (MapEntityBinder) arg; + } else if (arg instanceof MapRequestDecorator) { + MapRequestDecorator binder = (MapRequestDecorator) arg; injector.injectMembers(binder); return binder; } @@ -494,7 +561,7 @@ public class JaxrsAnnotationProcessor { return null; } - private Map constants = Maps.newHashMap(); + private Multimap constants = HashMultimap.create(); public boolean isHttpMethod(Method method) { return IsHttpMethod.getHttpMethods(method) != null; @@ -528,49 +595,41 @@ public class JaxrsAnnotationProcessor { } } - public HttpRequest buildEntityIfPostOrPutRequest(Method method, Object[] args, - HttpRequest request) { - OUTER: if (request.getMethod().toUpperCase().equals("POST") - || request.getMethod().toUpperCase().equals("PUT")) { - MapEntityBinder mapBinder = getMapEntityBinderOrNull(method, args); - Map mapParams = buildPostParams(method, args); - // MapEntityBinder is only useful if there are parameters. We guard here in case the - // MapEntityBinder is also an EntityBinder. If so, it can be used with or without - // parameters. - if (mapBinder != null) { - mapBinder.addEntityToRequest(mapParams, request); - break OUTER; - } - HttpRequestOptions options = findOptionsIn(method, args); - if (options != null) { - optionsBinder.addEntityToRequest(options, request); - } - if (request.getEntity() == null) { + public HttpRequest decorateRequest(Method method, Object[] args, HttpRequest request) { + MapRequestDecorator mapBinder = getMapEntityBinderOrNull(method, args); + Map mapParams = buildPostParams(method, args); + // MapEntityBinder is only useful if there are parameters. We guard here in case the + // MapEntityBinder is also an EntityBinder. If so, it can be used with or without + // parameters. + if (mapBinder != null) { + mapBinder.decorateRequest(request, mapParams); + return request; + } - Map> indexToEntityAnnotation = indexWithOnlyOneAnnotation( - method, "@Entity", methodToIndexOfParamToEntityAnnotation); - - if (indexToEntityAnnotation.size() == 1) { - Entry> entry = indexToEntityAnnotation.entrySet() - .iterator().next(); - EntityParam entityAnnotation = (EntityParam) entry.getValue().iterator().next(); - - EntityBinder binder = injector.getInstance(entityAnnotation.value()); - Object entity = args[entry.getKey()]; - if (entity.getClass().isArray()) { - Object[] entityArray = (Object[]) entity; - entity = entityArray.length > 0 ? entityArray[0] : null; - } - if (entity != null) - binder.addEntityToRequest(entity, request); - } else if (indexToEntityAnnotation.size() > 1) { - throw new IllegalStateException("cannot have multiple @Entity annotations on " - + method); - } else { - request.getHeaders().replaceValues(HttpHeaders.CONTENT_LENGTH, - Lists.newArrayList("0")); - } + for (Entry> entry : Maps.filterValues( + methodToIndexOfParamToDecoratorParamAnnotation.get(method), + new Predicate>() { + public boolean apply(Set input) { + return input.size() >= 1; + } + }).entrySet()) { + DecoratorParam entityAnnotation = (DecoratorParam) entry.getValue().iterator().next(); + RequestDecorator binder = injector.getInstance(entityAnnotation.value()); + Object input = args[entry.getKey()]; + if (input.getClass().isArray()) { + Object[] entityArray = (Object[]) input; + input = entityArray.length > 0 ? entityArray[0] : null; } + Object oldEntity = request.getEntity(); + request = binder.decorateRequest(request, input); + if (oldEntity != null && !oldEntity.equals(request.getEntity())) { + throw new IllegalStateException(String.format( + "binder %s replaced the previous entity on request: %s", binder, request)); + } + } + if (request.getMethod().equals("PUT") && request.getEntity() == null) { + request.getHeaders().replaceValues(HttpHeaders.CONTENT_LENGTH, + Collections.singletonList(0 + "")); } return request; } @@ -619,46 +678,85 @@ public class JaxrsAnnotationProcessor { return null; } - public Multimap buildHeaders(Method method, final Object[] args) { + public Multimap buildHeaders(Method method, final Object[] args, + Collection> tokenValues) { Multimap headers = HashMultimap.create(); + addHeaderIfAnnotationPresentOnMethod(headers, method, tokenValues); Map> indexToHeaderParam = methodToIndexOfParamToHeaderParamAnnotations .get(method); for (Entry> entry : indexToHeaderParam.entrySet()) { for (Annotation key : entry.getValue()) { - headers.put(((HeaderParam) key).value(), args[entry.getKey()].toString()); + String value = args[entry.getKey()].toString(); + value = replaceTokens(value, tokenValues); + headers.put(((HeaderParam) key).value(), value); } } + addProducesIfPresentOnTypeOrMethod(headers, method); + addConsumesIfPresentOnTypeOrMethod(headers, method); return headers; } - public void addHeaderIfAnnotationPresentOnMethod(Multimap headers, - Method method, Object[] args, char... skipEncode) throws UnsupportedEncodingException { - if (declaring.isAnnotationPresent(Headers.class)) { - Headers header = declaring.getAnnotation(Headers.class); - addHeader(headers, method, args, header); + void addConsumesIfPresentOnTypeOrMethod(Multimap headers, Method method) { + if (declaring.isAnnotationPresent(Consumes.class)) { + Consumes header = declaring.getAnnotation(Consumes.class); + headers.replaceValues(HttpHeaders.ACCEPT, Arrays.asList(header.value())); } - if (method.isAnnotationPresent(Headers.class)) { - Headers header = method.getAnnotation(Headers.class); - addHeader(headers, method, args, header); + if (method.isAnnotationPresent(Consumes.class)) { + Consumes header = method.getAnnotation(Consumes.class); + headers.replaceValues(HttpHeaders.ACCEPT, Arrays.asList(header.value())); } } - private void addHeader(Multimap headers, Method method, Object[] args, - Headers header) throws UnsupportedEncodingException { + void addProducesIfPresentOnTypeOrMethod(Multimap headers, Method method) { + if (declaring.isAnnotationPresent(Produces.class)) { + Produces header = declaring.getAnnotation(Produces.class); + headers.replaceValues(HttpHeaders.CONTENT_TYPE, Arrays.asList(header.value())); + } + if (method.isAnnotationPresent(Produces.class)) { + Produces header = method.getAnnotation(Produces.class); + headers.replaceValues(HttpHeaders.CONTENT_TYPE, Arrays.asList(header.value())); + } + } + + public void addHeaderIfAnnotationPresentOnMethod(Multimap headers, + Method method, Collection> tokenValues) { + if (declaring.isAnnotationPresent(Headers.class)) { + Headers header = declaring.getAnnotation(Headers.class); + addHeader(headers, header, tokenValues); + } + if (method.isAnnotationPresent(Headers.class)) { + Headers header = method.getAnnotation(Headers.class); + addHeader(headers, header, tokenValues); + } + } + + private void addHeader(Multimap headers, Headers header, + Collection> tokenValues) { for (int i = 0; i < header.keys().length; i++) { String value = header.values()[i]; - for (Entry tokenValue : getEncodedPathParamKeyValues(method, args) - .entrySet()) { - value = value.replaceAll("\\{" + tokenValue.getKey() + "\\}", tokenValue.getValue()); - } + value = replaceTokens(value, tokenValues); headers.put(header.keys()[i], value); } } - private Map getEncodedPathParamKeyValues(Method method, Object[] args, - final char... skipEncode) throws UnsupportedEncodingException { - Map pathParamValues = Maps.newHashMap(); + private String replaceTokens(String value, Collection> tokenValues) { + for (Entry tokenValue : tokenValues) { + value = value.replaceAll("\\{" + tokenValue.getKey() + "\\}", tokenValue.getValue()); + } + return value; + } + + private Map convertUnsafe(Multimap in) { + Map out = Maps.newHashMap(); + for (Entry entry : in.entries()) { + out.put(entry.getKey(), entry.getValue()); + } + return out; + } + + private Multimap getPathParamKeyValues(Method method, Object[] args) { + Multimap pathParamValues = HashMultimap.create(); pathParamValues.putAll(constants); Map> indexToPathParam = methodToindexOfParamToPathParamAnnotations .get(method); @@ -686,30 +784,50 @@ public class JaxrsAnnotationProcessor { String paramValue = injector.getInstance(method.getAnnotation(ParamParser.class).value()) .apply(args); pathParamValues.put(paramKey, paramValue); - } - return Maps.transformValues(pathParamValues, new Function() { - public String apply(String paramValue) { - try { - paramValue = URLEncoder.encode(paramValue, "UTF-8"); - // Web browsers do not always handle '+' characters well, use the well-supported - // '%20' instead. - paramValue = paramValue.replaceAll("\\+", "%20"); - for (char c : skipEncode) { - String value = Character.toString(c); - String encoded = URLEncoder.encode(value, "UTF-8"); - paramValue = paramValue.replaceAll(encoded, value); - } - } catch (UnsupportedEncodingException e) { - throw new RuntimeException("jclouds only supports UTF-8", e); - } - return paramValue; - } - }); + } + return pathParamValues; } - private Map getQueryParamKeyValues(Method method, Object[] args) { - Map queryParamValues = Maps.newHashMap(); + private Multimap encodeValues(Multimap unencoded, + final char... skipEncode) { + Multimap encoded = HashMultimap.create(); + for (Entry entry : unencoded.entries()) { + try { + String value = URLEncoder.encode(entry.getValue(), "UTF-8"); + // Web browsers do not always handle '+' characters well, use the well-supported + // '%20' instead. + value = value.replaceAll("\\+", "%20"); + for (char c : skipEncode) { + String toSkip = Character.toString(c); + String encodedValueToSkip = URLEncoder.encode(toSkip, "UTF-8"); + value = value.replaceAll(encodedValueToSkip, toSkip); + } + encoded.put(entry.getKey(), value); + } catch (UnsupportedEncodingException e) { + throw new RuntimeException("jclouds only supports UTF-8", e); + } + } + return encoded; + } + + private Multimap getMatrixParamKeyValues(Method method, Object[] args) { + Multimap queryParamValues = HashMultimap.create(); + queryParamValues.putAll(constants); + Map> indexToMatrixParam = methodToindexOfParamToMatrixParamAnnotations + .get(method); + for (Entry> entry : indexToMatrixParam.entrySet()) { + for (Annotation key : entry.getValue()) { + String paramKey = ((MatrixParam) key).value(); + String paramValue = args[entry.getKey()].toString(); + queryParamValues.put(paramKey, paramValue); + } + } + return queryParamValues; + } + + private Multimap getQueryParamKeyValues(Method method, Object[] args) { + Multimap queryParamValues = HashMultimap.create(); queryParamValues.putAll(constants); Map> indexToQueryParam = methodToindexOfParamToQueryParamAnnotations .get(method); diff --git a/core/src/main/java/org/jclouds/rest/RestClientProxy.java b/core/src/main/java/org/jclouds/rest/internal/RestClientProxy.java old mode 100644 new mode 100755 similarity index 92% rename from core/src/main/java/org/jclouds/rest/RestClientProxy.java rename to core/src/main/java/org/jclouds/rest/internal/RestClientProxy.java index f82c5e03a1..0c05d742d2 --- a/core/src/main/java/org/jclouds/rest/RestClientProxy.java +++ b/core/src/main/java/org/jclouds/rest/internal/RestClientProxy.java @@ -21,7 +21,7 @@ * under the License. * ==================================================================== */ -package org.jclouds.rest; +package org.jclouds.rest.internal; /** * Generates RESTful clients from appropriately annotated interfaces. @@ -46,13 +46,14 @@ import org.jclouds.http.HttpRequest; import org.jclouds.http.HttpResponse; import org.jclouds.http.TransformingHttpCommand; import org.jclouds.logging.Logger; +import org.jclouds.rest.InvocationContext; import com.google.common.base.Function; import com.google.inject.TypeLiteral; @Singleton public class RestClientProxy implements InvocationHandler { - private final JaxrsAnnotationProcessor util; + private final RestAnnotationProcessor util; private final Class declaring; private final TransformingHttpCommand.Factory commandFactory; @@ -69,7 +70,7 @@ public class RestClientProxy implements InvocationHandler { @SuppressWarnings("unchecked") @Inject public RestClientProxy(TransformingHttpCommand.Factory factory, - JaxrsAnnotationProcessor util, TypeLiteral typeLiteral) { + RestAnnotationProcessor util, TypeLiteral typeLiteral) { this.util = util; this.declaring = (Class) typeLiteral.getRawType(); this.commandFactory = factory; @@ -87,14 +88,14 @@ public class RestClientProxy implements InvocationHandler { Function exceptionParser = util .createExceptionParserOrNullIfNotFound(method); // in case there is an exception creating the request, we should at least pass in args - if (exceptionParser instanceof RestContext) { - ((RestContext) exceptionParser).setContext(null, args); + if (exceptionParser instanceof InvocationContext) { + ((InvocationContext) exceptionParser).setContext(null, args); } HttpRequest request; try { request = util.createRequest(method, args); - if (exceptionParser instanceof RestContext) { - ((RestContext) exceptionParser).setContext(request, args); + if (exceptionParser instanceof InvocationContext) { + ((InvocationContext) exceptionParser).setContext(request, args); } } catch (RuntimeException e) { if (exceptionParser != null) { diff --git a/core/src/main/java/org/jclouds/rest/RuntimeDelegateImpl.java b/core/src/main/java/org/jclouds/rest/internal/RuntimeDelegateImpl.java old mode 100644 new mode 100755 similarity index 98% rename from core/src/main/java/org/jclouds/rest/RuntimeDelegateImpl.java rename to core/src/main/java/org/jclouds/rest/internal/RuntimeDelegateImpl.java index 9ff89942b6..7680516c94 --- a/core/src/main/java/org/jclouds/rest/RuntimeDelegateImpl.java +++ b/core/src/main/java/org/jclouds/rest/internal/RuntimeDelegateImpl.java @@ -21,7 +21,7 @@ * under the License. * ==================================================================== */ -package org.jclouds.rest; +package org.jclouds.rest.internal; import javax.ws.rs.core.Application; import javax.ws.rs.core.UriBuilder; diff --git a/core/src/test/java/org/jclouds/http/BaseJettyTest.java b/core/src/test/java/org/jclouds/http/BaseJettyTest.java index c22a0e8a70..9015eda246 100644 --- a/core/src/test/java/org/jclouds/http/BaseJettyTest.java +++ b/core/src/test/java/org/jclouds/http/BaseJettyTest.java @@ -41,7 +41,7 @@ import org.jclouds.cloud.ConfiguresCloudConnection; import org.jclouds.cloud.internal.CloudContextImpl; import org.jclouds.lifecycle.Closer; import org.jclouds.rest.RestClientFactory; -import org.jclouds.rest.JaxrsAnnotationProcessorTest.Localhost; +import org.jclouds.rest.RestAnnotationProcessorTest.Localhost; import org.jclouds.util.Jsr330; import org.jclouds.util.Utils; import org.mortbay.jetty.Handler; diff --git a/core/src/test/java/org/jclouds/http/IntegrationTestClient.java b/core/src/test/java/org/jclouds/http/IntegrationTestClient.java index 968d4f8558..1deed18c44 100644 --- a/core/src/test/java/org/jclouds/http/IntegrationTestClient.java +++ b/core/src/test/java/org/jclouds/http/IntegrationTestClient.java @@ -33,17 +33,18 @@ import javax.ws.rs.PUT; import javax.ws.rs.Path; import javax.ws.rs.PathParam; -import org.jclouds.rest.binders.JsonBinder; import org.jclouds.http.functions.ParseSax; import org.jclouds.http.options.HttpRequestOptions; -import org.jclouds.rest.Endpoint; -import org.jclouds.rest.EntityParam; -import org.jclouds.rest.ExceptionParser; -import org.jclouds.rest.MapBinder; -import org.jclouds.rest.MapEntityParam; -import org.jclouds.rest.RequestFilters; -import org.jclouds.rest.XMLResponseParser; -import org.jclouds.rest.JaxrsAnnotationProcessorTest.Localhost; +import org.jclouds.rest.RestAnnotationProcessorTest.Localhost; +import org.jclouds.rest.annotations.DecoratorParam; +import org.jclouds.rest.annotations.Endpoint; +import org.jclouds.rest.annotations.ExceptionParser; +import org.jclouds.rest.annotations.MapBinder; +import org.jclouds.rest.annotations.MapEntityParam; +import org.jclouds.rest.annotations.RequestFilters; +import org.jclouds.rest.annotations.XMLResponseParser; +import org.jclouds.rest.decorators.AddAsJsonEntity; +import org.jclouds.rest.decorators.AddAsStringEntity; import com.google.common.base.Function; @@ -87,15 +88,15 @@ public interface IntegrationTestClient { @PUT @Path("objects/{id}") - Future upload(@PathParam("id") String id, @EntityParam String toPut); + Future upload(@PathParam("id") String id, @DecoratorParam(AddAsStringEntity.class) String toPut); @POST @Path("objects/{id}") - Future post(@PathParam("id") String id, @EntityParam String toPut); + Future post(@PathParam("id") String id, @DecoratorParam(AddAsStringEntity.class) String toPut); @POST @Path("objects/{id}") - @MapBinder(JsonBinder.class) + @MapBinder(AddAsJsonEntity.class) Future postJson(@PathParam("id") String id, @MapEntityParam("key") String toPut); @GET diff --git a/core/src/test/java/org/jclouds/rest/JaxrsAnnotationProcessorTest.java b/core/src/test/java/org/jclouds/rest/RestAnnotationProcessorTest.java old mode 100644 new mode 100755 similarity index 75% rename from core/src/test/java/org/jclouds/rest/JaxrsAnnotationProcessorTest.java rename to core/src/test/java/org/jclouds/rest/RestAnnotationProcessorTest.java index 410b2de375..acbafbe321 --- a/core/src/test/java/org/jclouds/rest/JaxrsAnnotationProcessorTest.java +++ b/core/src/test/java/org/jclouds/rest/RestAnnotationProcessorTest.java @@ -43,6 +43,7 @@ import java.util.concurrent.Future; import javax.inject.Named; import javax.inject.Qualifier; +import javax.ws.rs.Consumes; import javax.ws.rs.GET; import javax.ws.rs.HeaderParam; import javax.ws.rs.HttpMethod; @@ -50,7 +51,9 @@ import javax.ws.rs.POST; import javax.ws.rs.PUT; import javax.ws.rs.Path; import javax.ws.rs.PathParam; +import javax.ws.rs.Produces; import javax.ws.rs.QueryParam; +import javax.ws.rs.core.MediaType; import org.jclouds.concurrent.WithinThreadExecutorService; import org.jclouds.concurrent.config.ExecutorServiceModule; @@ -67,10 +70,25 @@ import org.jclouds.http.functions.ReturnVoidIf2xx; import org.jclouds.http.options.BaseHttpRequestOptions; import org.jclouds.http.options.GetOptions; import org.jclouds.http.options.HttpRequestOptions; -import org.jclouds.rest.binders.HttpRequestOptionsBinder; -import org.jclouds.rest.binders.JsonBinder; -import org.jclouds.rest.binders.MapEntityBinder; -import org.jclouds.rest.config.JaxrsModule; +import org.jclouds.rest.InvocationContext; +import org.jclouds.rest.annotations.DecoratorParam; +import org.jclouds.rest.annotations.Endpoint; +import org.jclouds.rest.annotations.Headers; +import org.jclouds.rest.annotations.HostPrefixParam; +import org.jclouds.rest.annotations.MapBinder; +import org.jclouds.rest.annotations.MapEntityParam; +import org.jclouds.rest.annotations.MatrixParams; +import org.jclouds.rest.annotations.ParamParser; +import org.jclouds.rest.annotations.QueryParams; +import org.jclouds.rest.annotations.RequestFilters; +import org.jclouds.rest.annotations.ResponseParser; +import org.jclouds.rest.annotations.SkipEncoding; +import org.jclouds.rest.annotations.VirtualHost; +import org.jclouds.rest.config.RestModule; +import org.jclouds.rest.decorators.AddAsJsonEntity; +import org.jclouds.rest.decorators.AddAsStringEntity; +import org.jclouds.rest.decorators.MapRequestDecorator; +import org.jclouds.rest.internal.RestAnnotationProcessor; import org.jclouds.util.DateService; import org.jclouds.util.Jsr330; import org.joda.time.DateTime; @@ -81,6 +99,7 @@ import org.testng.annotations.Test; import com.google.common.base.Function; import com.google.common.collect.HashMultimap; +import com.google.common.collect.ImmutableMultimap; import com.google.common.collect.Multimap; import com.google.inject.AbstractModule; import com.google.inject.Guice; @@ -95,7 +114,7 @@ import com.google.inject.util.Types; * @author Adrian Cole */ @Test(groups = "unit", testName = "jaxrs.JaxrsUtilTest") -public class JaxrsAnnotationProcessorTest { +public class RestAnnotationProcessorTest { @Target( { ElementType.METHOD }) @Retention(RetentionPolicy.RUNTIME) @javax.ws.rs.HttpMethod("FOO") @@ -166,12 +185,11 @@ public class JaxrsAnnotationProcessorTest { @Endpoint(Localhost.class) public class TestEntityParamVarargs { @POST - public void varargs( - @EntityParam(HttpRequestOptionsBinder.class) HttpRequestOptions... options) { + public void varargs(HttpRequestOptions... options) { } @POST - public void post(@EntityParam(HttpRequestOptionsBinder.class) HttpRequestOptions options) { + public void post(HttpRequestOptions options) { } } @@ -293,22 +311,22 @@ public class JaxrsAnnotationProcessorTest { @Endpoint(Localhost.class) public class TestPost { @POST - public void post(@EntityParam String content) { + public void post(@DecoratorParam(AddAsStringEntity.class) String content) { } @POST - public void postAsJson(@EntityParam(JsonBinder.class) String content) { + public void postAsJson(@DecoratorParam(AddAsJsonEntity.class) String content) { } @POST @Path("{foo}") public void postWithPath(@PathParam("foo") @MapEntityParam("fooble") String path, - MapEntityBinder content) { + MapRequestDecorator content) { } @POST @Path("{foo}") - @MapBinder(JsonBinder.class) + @MapBinder(AddAsJsonEntity.class) public void postWithMethodBinder(@PathParam("foo") @MapEntityParam("fooble") String path) { } } @@ -344,14 +362,17 @@ public class JaxrsAnnotationProcessorTest { } public void testCreatePostWithPathRequest() throws SecurityException, NoSuchMethodException { - Method method = TestPost.class.getMethod("postWithPath", String.class, MapEntityBinder.class); + Method method = TestPost.class.getMethod("postWithPath", String.class, + MapRequestDecorator.class); HttpRequest httpMethod = factory(TestPost.class).createRequest(method, - new Object[] { "data", new MapEntityBinder() { - public void addEntityToRequest(Map postParams, HttpRequest request) { + new Object[] { "data", new MapRequestDecorator() { + public HttpRequest decorateRequest(HttpRequest request, + Map postParams) { request.setEntity(postParams.get("fooble")); + return request; } - public void addEntityToRequest(Object toBind, HttpRequest request) { + public HttpRequest decorateRequest(HttpRequest request, Object toBind) { throw new RuntimeException("this shouldn't be used in POST"); } } }); @@ -382,9 +403,24 @@ public class JaxrsAnnotationProcessorTest { public class TestPut { @PUT @Path("{foo}") - @MapBinder(JsonBinder.class) + @MapBinder(AddAsJsonEntity.class) public void putWithMethodBinder(@PathParam("foo") @MapEntityParam("fooble") String path) { } + + @PUT + @Path("{foo}") + @Produces(MediaType.TEXT_PLAIN) + public void putWithMethodBinderProduces( + @PathParam("foo") @DecoratorParam(AddAsStringEntity.class) String path) { + } + + @PUT + @Path("{foo}") + @MapBinder(AddAsJsonEntity.class) + @Consumes(MediaType.APPLICATION_JSON) + public void putWithMethodBinderConsumes( + @PathParam("foo") @MapEntityParam("fooble") String path) { + } } public void testCreatePutWithMethodBinder() throws SecurityException, NoSuchMethodException { @@ -402,6 +438,40 @@ public class JaxrsAnnotationProcessorTest { .singletonList(expected.getBytes().length + "")); assertEquals(httpMethod.getEntity(), expected); } + + public void testCreatePutWithMethodProduces() throws SecurityException, NoSuchMethodException { + Method method = TestPut.class.getMethod("putWithMethodBinderProduces", String.class); + HttpRequest httpMethod = factory(TestPut.class).createRequest(method, + new Object[] { "data", }); + assertEquals(httpMethod.getEndpoint().getHost(), "localhost"); + assertEquals(httpMethod.getEndpoint().getPath(), "/data"); + assertEquals(httpMethod.getMethod(), HttpMethod.PUT); + assertEquals(httpMethod.getHeaders().size(), 2); + assertEquals(httpMethod.getHeaders().get(HttpHeaders.CONTENT_TYPE), Collections + .singletonList("text/plain")); + assertEquals(httpMethod.getHeaders().get(HttpHeaders.CONTENT_LENGTH), Collections + .singletonList("data".getBytes().length + "")); + assertEquals(httpMethod.getEntity(), "data"); + } + + public void testCreatePutWithMethodConsumes() throws SecurityException, NoSuchMethodException { + Method method = TestPut.class.getMethod("putWithMethodBinderConsumes", String.class); + HttpRequest httpMethod = factory(TestPut.class).createRequest(method, + new Object[] { "data", }); + assertEquals(httpMethod.getEndpoint().getHost(), "localhost"); + assertEquals(httpMethod.getEndpoint().getPath(), "/data"); + assertEquals(httpMethod.getMethod(), HttpMethod.PUT); + assertEquals(httpMethod.getHeaders().size(), 3); + assertEquals(httpMethod.getHeaders().get(HttpHeaders.CONTENT_TYPE), Collections + .singletonList("application/json")); + assertEquals(httpMethod.getHeaders().get(HttpHeaders.ACCEPT), Collections + .singletonList("application/json")); + String expected = "{\"fooble\":\"data\"}"; + assertEquals(httpMethod.getHeaders().get(HttpHeaders.CONTENT_LENGTH), Collections + .singletonList(expected.getBytes().length + "")); + assertEquals(httpMethod.getEntity(), expected); + } + static class TestRequestFilter1 implements HttpRequestFilter { public HttpRequest filter(HttpRequest request) throws HttpException { @@ -578,9 +648,8 @@ public class JaxrsAnnotationProcessorTest { public void testBuildTwoHeader() throws SecurityException, NoSuchMethodException, UnsupportedEncodingException { Method oneHeader = TestHeader.class.getMethod("twoHeader", String.class); - Multimap headers = HashMultimap.create(); - factory(TestHeader.class).addHeaderIfAnnotationPresentOnMethod(headers, oneHeader, - new Object[] { "robot" }); + Multimap headers = factory(TestHeader.class).createRequest(oneHeader, + new Object[] { "robot" }).getHeaders(); assertEquals(headers.size(), 2); assertEquals(headers.get("slash"), Collections.singletonList("/robot")); assertEquals(headers.get("hyphen"), Collections.singletonList("-robot")); @@ -598,9 +667,8 @@ public class JaxrsAnnotationProcessorTest { public void testBuildOneClassHeader() throws SecurityException, NoSuchMethodException, UnsupportedEncodingException { Method oneHeader = TestClassHeader.class.getMethod("oneHeader", String.class); - Multimap headers = HashMultimap.create(); - factory(TestClassHeader.class).addHeaderIfAnnotationPresentOnMethod(headers, oneHeader, - new Object[] { "robot" }); + Multimap headers = factory(TestClassHeader.class).createRequest(oneHeader, + new Object[] { "robot" }).getHeaders(); assertEquals(headers.size(), 1); assertEquals(headers.get("x-amz-copy-source"), Collections.singletonList("/robot")); } @@ -609,9 +677,8 @@ public class JaxrsAnnotationProcessorTest { public void testBuildOneHeader() throws SecurityException, NoSuchMethodException, UnsupportedEncodingException { Method oneHeader = TestHeader.class.getMethod("oneHeader", String.class); - Multimap headers = HashMultimap.create(); - factory(TestHeader.class).addHeaderIfAnnotationPresentOnMethod(headers, oneHeader, - new Object[] { "robot" }); + Multimap headers = factory(TestHeader.class).createRequest(oneHeader, + new Object[] { "robot" }).getHeaders(); assertEquals(headers.size(), 1); assertEquals(headers.get("x-amz-copy-source"), Collections.singletonList("/robot")); } @@ -620,9 +687,8 @@ public class JaxrsAnnotationProcessorTest { public void testBuildTwoHeaders() throws SecurityException, NoSuchMethodException, UnsupportedEncodingException { Method twoHeaders = TestHeader.class.getMethod("twoHeaders", String.class, String.class); - Multimap headers = HashMultimap.create(); - factory(TestHeader.class).addHeaderIfAnnotationPresentOnMethod(headers, twoHeaders, - new Object[] { "robot", "eggs" }); + Multimap headers = factory(TestHeader.class).createRequest(twoHeaders, + new Object[] { "robot", "eggs" }).getHeaders(); assertEquals(headers.size(), 1); assertEquals(headers.get("x-amz-copy-source"), Collections.singletonList("/robot/eggs")); } @@ -632,13 +698,213 @@ public class JaxrsAnnotationProcessorTest { UnsupportedEncodingException { Method twoHeadersOutOfOrder = TestHeader.class.getMethod("twoHeadersOutOfOrder", String.class, String.class); - Multimap headers = HashMultimap.create(); - factory(TestHeader.class).addHeaderIfAnnotationPresentOnMethod(headers, twoHeadersOutOfOrder, - new Object[] { "robot", "eggs" }); + Multimap headers = factory(TestHeader.class).createRequest( + twoHeadersOutOfOrder, new Object[] { "robot", "eggs" }).getHeaders(); assertEquals(headers.size(), 1); assertEquals(headers.get("x-amz-copy-source"), Collections.singletonList("/eggs/robot")); } + public class TestReplaceQueryOptions extends BaseHttpRequestOptions { + public TestReplaceQueryOptions() { + this.queryParameters.put("x-amz-copy-source", "/{bucket}"); + } + } + + @Test + public void testQueryInOptions() throws SecurityException, NoSuchMethodException, + UnsupportedEncodingException { + Method oneQuery = TestQueryReplace.class.getMethod("queryInOptions", String.class, + TestReplaceQueryOptions.class); + String query = factory(TestQueryReplace.class).createRequest(oneQuery, + new Object[] { "robot", new TestReplaceQueryOptions() }).getEndpoint().getQuery(); + assertEquals(query, "x-amz-copy-source=/robot"); + } + + @Endpoint(Localhost.class) + public class TestQueryReplace { + + @GET + public void queryInOptions(@PathParam("bucket") String path, TestReplaceQueryOptions options) { + } + + @GET + @QueryParams(keys = "x-amz-copy-source", values = "/{bucket}") + public void oneQuery(@PathParam("bucket") String path) { + } + + @GET + @QueryParams(keys = { "slash", "hyphen" }, values = { "/{bucket}", "-{bucket}" }) + public void twoQuery(@PathParam("bucket") String path) { + } + + @GET + @QueryParams(keys = "x-amz-copy-source", values = "/{bucket}/{key}") + public void twoQuerys(@PathParam("bucket") String path, @PathParam("key") String path2) { + } + + @GET + @QueryParams(keys = "x-amz-copy-source", values = "/{bucket}/{key}") + public void twoQuerysOutOfOrder(@PathParam("key") String path, + @PathParam("bucket") String path2) { + } + } + + @Test + public void testBuildTwoQuery() throws SecurityException, NoSuchMethodException, + UnsupportedEncodingException { + Method oneQuery = TestQueryReplace.class.getMethod("twoQuery", String.class); + String query = factory(TestQueryReplace.class).createRequest(oneQuery, + new Object[] { "robot" }).getEndpoint().getQuery(); + assertEquals(query, "slash=/robot&hyphen=-robot"); + } + + @QueryParams(keys = "x-amz-copy-source", values = "/{bucket}") + @Endpoint(Localhost.class) + public class TestClassQuery { + @GET + public void oneQuery(@PathParam("bucket") String path) { + } + } + + @Test + public void testBuildOneClassQuery() throws SecurityException, NoSuchMethodException, + UnsupportedEncodingException { + Method oneQuery = TestClassQuery.class.getMethod("oneQuery", String.class); + String query = factory(TestClassQuery.class) + .createRequest(oneQuery, new Object[] { "robot" }).getEndpoint().getQuery(); + assertEquals(query, "x-amz-copy-source=/robot"); + } + + @Test + public void testBuildOneQuery() throws SecurityException, NoSuchMethodException, + UnsupportedEncodingException { + Method oneQuery = TestQueryReplace.class.getMethod("oneQuery", String.class); + String query = factory(TestQueryReplace.class).createRequest(oneQuery, + new Object[] { "robot" }).getEndpoint().getQuery(); + assertEquals(query, "x-amz-copy-source=/robot"); + } + + @Test + public void testBuildTwoQuerys() throws SecurityException, NoSuchMethodException, + UnsupportedEncodingException { + Method twoQuerys = TestQueryReplace.class.getMethod("twoQuerys", String.class, String.class); + String query = factory(TestQueryReplace.class).createRequest(twoQuerys, + new Object[] { "robot", "eggs" }).getEndpoint().getQuery(); + assertEquals(query, "x-amz-copy-source=/robot/eggs"); + } + + @Test + public void testBuildTwoQuerysOutOfOrder() throws SecurityException, NoSuchMethodException, + UnsupportedEncodingException { + Method twoQuerysOutOfOrder = TestQueryReplace.class.getMethod("twoQuerysOutOfOrder", + String.class, String.class); + String query = factory(TestQueryReplace.class).createRequest(twoQuerysOutOfOrder, + new Object[] { "robot", "eggs" }).getEndpoint().getQuery(); + assertEquals(query, "x-amz-copy-source=/eggs/robot"); + } + + public class TestReplaceMatrixOptions extends BaseHttpRequestOptions { + public TestReplaceMatrixOptions() { + this.matrixParameters.put("x-amz-copy-source", "/{bucket}"); + } + } + + @Test + public void testMatrixInOptions() throws SecurityException, NoSuchMethodException, + UnsupportedEncodingException { + Method oneMatrix = TestMatrixReplace.class.getMethod("matrixInOptions", String.class, + TestReplaceMatrixOptions.class); + String path = factory(TestMatrixReplace.class).createRequest(oneMatrix, + new Object[] { "robot", new TestReplaceMatrixOptions() }).getEndpoint().getPath(); + assertEquals(path, "/;x-amz-copy-source=/robot"); + } + + @Endpoint(Localhost.class) + @Path("/") + public class TestMatrixReplace { + + @GET + public void matrixInOptions(@PathParam("bucket") String path, TestReplaceMatrixOptions options) { + } + + @GET + @MatrixParams(keys = "x-amz-copy-source", values = "/{bucket}") + public void oneMatrix(@PathParam("bucket") String path) { + } + + @GET + @MatrixParams(keys = { "slash", "hyphen" }, values = { "/{bucket}", "-{bucket}" }) + public void twoMatrix(@PathParam("bucket") String path) { + } + + @GET + @MatrixParams(keys = "x-amz-copy-source", values = "/{bucket}/{key}") + public void twoMatrixs(@PathParam("bucket") String path, @PathParam("key") String path2) { + } + + @GET + @MatrixParams(keys = "x-amz-copy-source", values = "/{bucket}/{key}") + public void twoMatrixsOutOfOrder(@PathParam("key") String path, + @PathParam("bucket") String path2) { + } + } + + @Test + public void testBuildTwoMatrix() throws SecurityException, NoSuchMethodException, + UnsupportedEncodingException { + Method oneMatrix = TestMatrixReplace.class.getMethod("twoMatrix", String.class); + String path = factory(TestMatrixReplace.class).createRequest(oneMatrix, + new Object[] { "robot" }).getEndpoint().getPath(); + assertEquals(path, "/;slash=/robot;hyphen=-robot"); + } + + @MatrixParams(keys = "x-amz-copy-source", values = "/{bucket}") + @Endpoint(Localhost.class) + @Path("/") + public class TestClassMatrix { + @GET + public void oneMatrix(@PathParam("bucket") String path) { + } + } + + @Test + public void testBuildOneClassMatrix() throws SecurityException, NoSuchMethodException, + UnsupportedEncodingException { + Method oneMatrix = TestClassMatrix.class.getMethod("oneMatrix", String.class); + String path = factory(TestClassMatrix.class).createRequest(oneMatrix, + new Object[] { "robot" }).getEndpoint().getPath(); + assertEquals(path, "/;x-amz-copy-source=/robot"); + } + + @Test + public void testBuildOneMatrix() throws SecurityException, NoSuchMethodException, + UnsupportedEncodingException { + Method oneMatrix = TestMatrixReplace.class.getMethod("oneMatrix", String.class); + String path = factory(TestMatrixReplace.class).createRequest(oneMatrix, + new Object[] { "robot" }).getEndpoint().getPath(); + assertEquals(path, "/;x-amz-copy-source=/robot"); + } + + @Test + public void testBuildTwoMatrixs() throws SecurityException, NoSuchMethodException, + UnsupportedEncodingException { + Method twoMatrixs = TestMatrixReplace.class.getMethod("twoMatrixs", String.class, + String.class); + String path = factory(TestMatrixReplace.class).createRequest(twoMatrixs, + new Object[] { "robot", "eggs" }).getEndpoint().getPath(); + assertEquals(path, "/;x-amz-copy-source=/robot/eggs"); + } + + @Test + public void testBuildTwoMatrixsOutOfOrder() throws SecurityException, NoSuchMethodException, + UnsupportedEncodingException { + Method twoMatrixsOutOfOrder = TestMatrixReplace.class.getMethod("twoMatrixsOutOfOrder", + String.class, String.class); + String path = factory(TestMatrixReplace.class).createRequest(twoMatrixsOutOfOrder, + new Object[] { "robot", "eggs" }).getEndpoint().getPath(); + assertEquals(path, "/;x-amz-copy-source=/eggs/robot"); + } + @Endpoint(Localhost.class) public interface TestTransformers { @GET @@ -697,7 +963,7 @@ public class JaxrsAnnotationProcessorTest { assertEquals(transformer, ParseURIList.class); } - public static class ReturnStringIf200Context extends ReturnStringIf200 implements RestContext { + public static class ReturnStringIf200Context extends ReturnStringIf200 implements InvocationContext { private Object[] args; private HttpRequest request; @@ -783,7 +1049,7 @@ public class JaxrsAnnotationProcessorTest { @PUT @Path("/{id}") public Future put(@PathParam("id") @ParamParser(FirstCharacter.class) String id, - @EntityParam String payload) { + @DecoratorParam(AddAsStringEntity.class) String payload) { return null; } @@ -798,7 +1064,8 @@ public class JaxrsAnnotationProcessorTest { @Path("/{id}") @Headers(keys = "foo", values = "--{id}--") @ResponseParser(ReturnTrueIf2xx.class) - public Future putHeader(@PathParam("id") String id, @EntityParam String payload) { + public Future putHeader(@PathParam("id") String id, + @DecoratorParam(AddAsStringEntity.class) String payload) { return null; } } @@ -1080,7 +1347,7 @@ public class JaxrsAnnotationProcessorTest { public void testOneHeader() throws SecurityException, NoSuchMethodException { Method method = TestHeaders.class.getMethod("oneHeader", String.class); Multimap headers = factory(TestHeaders.class).buildHeaders(method, - new Object[] { "robot" }); + new Object[] { "robot" }, ImmutableMultimap. of().entries()); assertEquals(headers.size(), 1); assertEquals(headers.get("header"), Collections.singletonList("robot")); } @@ -1089,7 +1356,7 @@ public class JaxrsAnnotationProcessorTest { public void testOneIntHeader() throws SecurityException, NoSuchMethodException { Method method = TestHeaders.class.getMethod("oneIntHeader", int.class); Multimap headers = factory(TestHeaders.class).buildHeaders(method, - new Object[] { 1 }); + new Object[] { 1 }, ImmutableMultimap. of().entries()); assertEquals(headers.size(), 1); assertEquals(headers.get("header"), Collections.singletonList("1")); } @@ -1099,7 +1366,7 @@ public class JaxrsAnnotationProcessorTest { Method method = TestHeaders.class .getMethod("twoDifferentHeaders", String.class, String.class); Multimap headers = factory(TestHeaders.class).buildHeaders(method, - new Object[] { "robot", "egg" }); + new Object[] { "robot", "egg" }, ImmutableMultimap. of().entries()); assertEquals(headers.size(), 2); assertEquals(headers.get("header1"), Collections.singletonList("robot")); assertEquals(headers.get("header2"), Collections.singletonList("egg")); @@ -1109,7 +1376,7 @@ public class JaxrsAnnotationProcessorTest { public void testTwoSameHeaders() throws SecurityException, NoSuchMethodException { Method method = TestHeaders.class.getMethod("twoSameHeaders", String.class, String.class); Multimap headers = factory(TestHeaders.class).buildHeaders(method, - new Object[] { "robot", "egg" }); + new Object[] { "robot", "egg" }, ImmutableMultimap. of().entries()); assertEquals(headers.size(), 2); Collection values = headers.get("header"); assert values.contains("robot"); @@ -1119,22 +1386,23 @@ public class JaxrsAnnotationProcessorTest { @Endpoint(Localhost.class) public interface TestEntity { @PUT - public void put(@EntityParam String content); + public void put(@DecoratorParam(AddAsStringEntity.class) String content); @PUT @Path("{foo}") - public Future putWithPath(@PathParam("foo") String path, @EntityParam String content); + public Future putWithPath(@PathParam("foo") String path, + @DecoratorParam(AddAsStringEntity.class) String content); @PUT - public void twoEntities(@EntityParam String entity1, @EntityParam String entity2); + public void twoEntities(@DecoratorParam(AddAsStringEntity.class) String entity1, + @DecoratorParam(AddAsStringEntity.class) String entity2); } @Test public void testPut() throws SecurityException, NoSuchMethodException { Method method = TestEntity.class.getMethod("put", String.class); HttpRequest request = new HttpRequest(HttpMethod.PUT, URI.create("http://localhost:8080")); - factory(TestEntity.class).buildEntityIfPostOrPutRequest(method, new Object[] { "test" }, - request); + factory(TestEntity.class).decorateRequest(method, new Object[] { "test" }, request); assertEquals(request.getEntity(), "test"); assertEquals(request.getHeaders().get(HttpHeaders.CONTENT_TYPE), Collections .singletonList("application/unknown")); @@ -1149,8 +1417,7 @@ public class JaxrsAnnotationProcessorTest { public void putWithPath() throws SecurityException, NoSuchMethodException { Method method = TestEntity.class.getMethod("putWithPath", String.class, String.class); HttpRequest request = new HttpRequest(HttpMethod.PUT, URI.create("http://localhost:8080")); - factory(TestEntity.class).buildEntityIfPostOrPutRequest(method, - new Object[] { "rabble", "test" }, request); + factory(TestEntity.class).decorateRequest(method, new Object[] { "rabble", "test" }, request); assertEquals(request.getEntity(), "test"); assertEquals(request.getHeaders().get(HttpHeaders.CONTENT_TYPE), Collections .singletonList("application/unknown")); @@ -1162,14 +1429,14 @@ public class JaxrsAnnotationProcessorTest { public void testPutTwoEntities() throws SecurityException, NoSuchMethodException { Method method = TestEntity.class.getMethod("twoEntities", String.class, String.class); HttpRequest request = new HttpRequest(HttpMethod.PUT, URI.create("http://localhost:8080")); - factory(TestEntity.class).buildEntityIfPostOrPutRequest(method, - new Object[] { "test", "ralphie" }, request); + factory(TestEntity.class) + .decorateRequest(method, new Object[] { "test", "ralphie" }, request); } @SuppressWarnings("unchecked") - private JaxrsAnnotationProcessor factory(Class clazz) { - return ((JaxrsAnnotationProcessor) injector.getInstance(Key.get(TypeLiteral.get(Types - .newParameterizedType(JaxrsAnnotationProcessor.class, clazz))))); + private RestAnnotationProcessor factory(Class clazz) { + return ((RestAnnotationProcessor) injector.getInstance(Key.get(TypeLiteral.get(Types + .newParameterizedType(RestAnnotationProcessor.class, clazz))))); } Injector injector; @@ -1186,7 +1453,7 @@ public class JaxrsAnnotationProcessorTest { bind(URI.class).annotatedWith(Localhost2.class).toInstance( URI.create("http://localhost:8081")); } - }, new JaxrsModule(), new ExecutorServiceModule(new WithinThreadExecutorService()), + }, new RestModule(), new ExecutorServiceModule(new WithinThreadExecutorService()), new JavaUrlHttpCommandExecutorServiceModule()); } diff --git a/extensions/httpnio/src/main/java/org/jclouds/http/httpnio/pool/NioHttpCommandExecutionHandler.java b/extensions/httpnio/src/main/java/org/jclouds/http/httpnio/pool/NioHttpCommandExecutionHandler.java index 025a818f26..7712b0678a 100644 --- a/extensions/httpnio/src/main/java/org/jclouds/http/httpnio/pool/NioHttpCommandExecutionHandler.java +++ b/extensions/httpnio/src/main/java/org/jclouds/http/httpnio/pool/NioHttpCommandExecutionHandler.java @@ -85,7 +85,7 @@ public class NioHttpCommandExecutionHandler implements NHttpRequestExecutionHand if (rendezvous != null) { HttpRequest request = rendezvous.getCommand().getRequest(); for (HttpRequestFilter filter : request.getFilters()) { - filter.filter(request); + request = filter.filter(request); } return NioHttpUtils.convertToApacheRequest(request); } diff --git a/mezeo/pcs2/core/src/main/java/org/jclouds/mezeo/pcs2/PCSBlobStore.java b/mezeo/pcs2/core/src/main/java/org/jclouds/mezeo/pcs2/PCSBlobStore.java index fc19693d4c..9974f5a919 100644 --- a/mezeo/pcs2/core/src/main/java/org/jclouds/mezeo/pcs2/PCSBlobStore.java +++ b/mezeo/pcs2/core/src/main/java/org/jclouds/mezeo/pcs2/PCSBlobStore.java @@ -38,8 +38,8 @@ import org.jclouds.blobstore.functions.ReturnVoidOnNotFoundOr404; import org.jclouds.blobstore.functions.ThrowKeyNotFoundOn404; import org.jclouds.http.filters.BasicAuthentication; import org.jclouds.http.options.GetOptions; -import org.jclouds.mezeo.pcs2.binders.BlockBinder; -import org.jclouds.mezeo.pcs2.binders.CreateContainerBinder; +import org.jclouds.mezeo.pcs2.decorators.AddDataAndLength; +import org.jclouds.mezeo.pcs2.decorators.AddContainerNameAsXmlEntity; import org.jclouds.mezeo.pcs2.domain.ContainerMetadata; import org.jclouds.mezeo.pcs2.domain.FileMetadata; import org.jclouds.mezeo.pcs2.domain.PCSFile; @@ -57,15 +57,15 @@ import org.jclouds.mezeo.pcs2.functions.ReturnTrueIfContainerAlreadyExists; import org.jclouds.mezeo.pcs2.xml.CachingFileListToContainerMetadataListHandler; import org.jclouds.mezeo.pcs2.xml.FileListToFileMetadataListHandler; import org.jclouds.mezeo.pcs2.xml.FileMetadataHandler; -import org.jclouds.rest.Endpoint; -import org.jclouds.rest.EntityParam; -import org.jclouds.rest.ExceptionParser; -import org.jclouds.rest.Headers; -import org.jclouds.rest.ParamParser; -import org.jclouds.rest.RequestFilters; -import org.jclouds.rest.ResponseParser; -import org.jclouds.rest.SkipEncoding; -import org.jclouds.rest.XMLResponseParser; +import org.jclouds.rest.annotations.DecoratorParam; +import org.jclouds.rest.annotations.Endpoint; +import org.jclouds.rest.annotations.ExceptionParser; +import org.jclouds.rest.annotations.Headers; +import org.jclouds.rest.annotations.ParamParser; +import org.jclouds.rest.annotations.RequestFilters; +import org.jclouds.rest.annotations.ResponseParser; +import org.jclouds.rest.annotations.SkipEncoding; +import org.jclouds.rest.annotations.XMLResponseParser; /** * Provides access to Mezeo PCS v2 via their REST API. @@ -98,7 +98,7 @@ public interface PCSBlobStore extends BlobStore createContainer(@EntityParam(CreateContainerBinder.class) String container); + Future createContainer(@DecoratorParam(AddContainerNameAsXmlEntity.class) String container); @DELETE @ExceptionParser(ReturnVoidOnNotFoundOr404.class) @@ -124,7 +124,7 @@ public interface PCSBlobStore extends BlobStore putBlob(String containerName, - @EntityParam(BlockBinder.class) PCSFile object); + @DecoratorParam(AddDataAndLength.class) PCSFile object); // @POST // @Path("/containers/{containerResourceId}/contents") @@ -133,7 +133,7 @@ public interface PCSBlobStore extends BlobStore putBlob(String containerName, -// @EntityParam(PCSFileAsMultipartFormBinder.class) PCSFile object); +// @EntityParam(BlobAsMultipartFormBinder.class) PCSFile object); @DELETE @ExceptionParser(ReturnVoidOnNotFoundOr404.class) diff --git a/mezeo/pcs2/core/src/main/java/org/jclouds/mezeo/pcs2/PCSCloud.java b/mezeo/pcs2/core/src/main/java/org/jclouds/mezeo/pcs2/PCSCloud.java index c658593212..a6cc49a8cc 100755 --- a/mezeo/pcs2/core/src/main/java/org/jclouds/mezeo/pcs2/PCSCloud.java +++ b/mezeo/pcs2/core/src/main/java/org/jclouds/mezeo/pcs2/PCSCloud.java @@ -37,9 +37,9 @@ import org.jclouds.mezeo.pcs2.endpoints.RootContainer; import org.jclouds.mezeo.pcs2.endpoints.Shares; import org.jclouds.mezeo.pcs2.endpoints.Tags; import org.jclouds.mezeo.pcs2.xml.CloudXlinkHandler; -import org.jclouds.rest.Endpoint; -import org.jclouds.rest.RequestFilters; -import org.jclouds.rest.XMLResponseParser; +import org.jclouds.rest.annotations.Endpoint; +import org.jclouds.rest.annotations.RequestFilters; +import org.jclouds.rest.annotations.XMLResponseParser; /** * Provides URIs to PCS services via their REST API. diff --git a/mezeo/pcs2/core/src/main/java/org/jclouds/mezeo/pcs2/PCSConnection.java b/mezeo/pcs2/core/src/main/java/org/jclouds/mezeo/pcs2/PCSConnection.java index 5193f2983d..c3d5645f44 100644 --- a/mezeo/pcs2/core/src/main/java/org/jclouds/mezeo/pcs2/PCSConnection.java +++ b/mezeo/pcs2/core/src/main/java/org/jclouds/mezeo/pcs2/PCSConnection.java @@ -34,13 +34,13 @@ import javax.ws.rs.POST; import javax.ws.rs.PUT; import javax.ws.rs.Path; +import org.jclouds.blobstore.decorators.AddBlobEntityAsMultipartForm; import org.jclouds.blobstore.functions.ReturnVoidOnNotFoundOr404; import org.jclouds.blobstore.functions.ThrowKeyNotFoundOn404; import org.jclouds.http.filters.BasicAuthentication; -import org.jclouds.mezeo.pcs2.binders.BlockBinder; -import org.jclouds.mezeo.pcs2.binders.CreateContainerBinder; -import org.jclouds.mezeo.pcs2.binders.CreateFileBinder; -import org.jclouds.mezeo.pcs2.binders.PCSFileAsMultipartFormBinder; +import org.jclouds.mezeo.pcs2.decorators.AddDataAndLength; +import org.jclouds.mezeo.pcs2.decorators.AddContainerNameAsXmlEntity; +import org.jclouds.mezeo.pcs2.decorators.AddFileInfoAsXmlEntity; import org.jclouds.mezeo.pcs2.domain.ContainerMetadata; import org.jclouds.mezeo.pcs2.domain.FileMetadata; import org.jclouds.mezeo.pcs2.domain.PCSFile; @@ -48,13 +48,13 @@ import org.jclouds.mezeo.pcs2.endpoints.RootContainer; import org.jclouds.mezeo.pcs2.options.PutBlockOptions; import org.jclouds.mezeo.pcs2.xml.FileListToContainerMetadataListHandler; import org.jclouds.mezeo.pcs2.xml.FileListToFileMetadataListHandler; -import org.jclouds.rest.Endpoint; -import org.jclouds.rest.EntityParam; -import org.jclouds.rest.ExceptionParser; -import org.jclouds.rest.Headers; -import org.jclouds.rest.RequestFilters; -import org.jclouds.rest.SkipEncoding; -import org.jclouds.rest.XMLResponseParser; +import org.jclouds.rest.annotations.DecoratorParam; +import org.jclouds.rest.annotations.Endpoint; +import org.jclouds.rest.annotations.ExceptionParser; +import org.jclouds.rest.annotations.Headers; +import org.jclouds.rest.annotations.RequestFilters; +import org.jclouds.rest.annotations.SkipEncoding; +import org.jclouds.rest.annotations.XMLResponseParser; /** * Provides access to Mezeo PCS v2 via their REST API. @@ -79,12 +79,12 @@ public interface PCSConnection { @POST @Path("/contents") @Endpoint(RootContainer.class) - Future createContainer(@EntityParam(CreateContainerBinder.class) String container); + Future createContainer(@DecoratorParam(AddContainerNameAsXmlEntity.class) String container); @POST @Path("/contents") Future createContainer(@Endpoint URI parent, - @EntityParam(CreateContainerBinder.class) String container); + @DecoratorParam(AddContainerNameAsXmlEntity.class) String container); @DELETE @ExceptionParser(ReturnVoidOnNotFoundOr404.class) @@ -105,17 +105,17 @@ public interface PCSConnection { @POST @Path("/contents") Future uploadFile(@Endpoint URI container, - @EntityParam(PCSFileAsMultipartFormBinder.class) PCSFile object); + @DecoratorParam(AddBlobEntityAsMultipartForm.class) PCSFile object); @POST @Path("/contents") Future createFile(@Endpoint URI container, - @EntityParam(CreateFileBinder.class) PCSFile object); + @DecoratorParam(AddFileInfoAsXmlEntity.class) PCSFile object); @PUT @Path("/content") Future uploadBlock(@Endpoint URI file, - @EntityParam(BlockBinder.class) PCSFile object, PutBlockOptions ... options); + @DecoratorParam(AddDataAndLength.class) PCSFile object, PutBlockOptions ... options); @DELETE @ExceptionParser(ReturnVoidOnNotFoundOr404.class) diff --git a/mezeo/pcs2/core/src/main/java/org/jclouds/mezeo/pcs2/PCSUtil.java b/mezeo/pcs2/core/src/main/java/org/jclouds/mezeo/pcs2/PCSUtil.java index 222fb6affc..2b2cc66b8a 100644 --- a/mezeo/pcs2/core/src/main/java/org/jclouds/mezeo/pcs2/PCSUtil.java +++ b/mezeo/pcs2/core/src/main/java/org/jclouds/mezeo/pcs2/PCSUtil.java @@ -33,11 +33,12 @@ import javax.ws.rs.PathParam; import org.jclouds.http.filters.BasicAuthentication; import org.jclouds.mezeo.pcs2.functions.AddEntryIntoMultiMap; -import org.jclouds.rest.Endpoint; -import org.jclouds.rest.EntityParam; -import org.jclouds.rest.RequestFilters; -import org.jclouds.rest.ResponseParser; -import org.jclouds.rest.SkipEncoding; +import org.jclouds.rest.annotations.DecoratorParam; +import org.jclouds.rest.annotations.Endpoint; +import org.jclouds.rest.annotations.RequestFilters; +import org.jclouds.rest.annotations.ResponseParser; +import org.jclouds.rest.annotations.SkipEncoding; +import org.jclouds.rest.decorators.AddAsStringEntity; import com.google.common.collect.Multimap; @@ -58,7 +59,7 @@ public interface PCSUtil { @Endpoint(PCS.class) @Path("/files/{fileResourceId}/metadata/{key}") Future putMetadata(@PathParam("fileResourceId") String resourceId, - @PathParam("key") String key, @EntityParam String value); + @PathParam("key") String key, @DecoratorParam(AddAsStringEntity.class) String value); @GET @ResponseParser(AddEntryIntoMultiMap.class) diff --git a/mezeo/pcs2/core/src/main/java/org/jclouds/mezeo/pcs2/config/PCSContextModule.java b/mezeo/pcs2/core/src/main/java/org/jclouds/mezeo/pcs2/config/PCSContextModule.java index 9ccccb0cf7..21ba3cacbd 100644 --- a/mezeo/pcs2/core/src/main/java/org/jclouds/mezeo/pcs2/config/PCSContextModule.java +++ b/mezeo/pcs2/core/src/main/java/org/jclouds/mezeo/pcs2/config/PCSContextModule.java @@ -35,6 +35,7 @@ import javax.inject.Singleton; import org.jclouds.blobstore.BlobStore; import org.jclouds.blobstore.BlobStoreContextImpl; import org.jclouds.blobstore.BlobMap.Factory; +import org.jclouds.blobstore.domain.Key; import org.jclouds.lifecycle.Closer; import org.jclouds.mezeo.pcs2.PCS; import org.jclouds.mezeo.pcs2.PCSConnection; @@ -44,7 +45,6 @@ import org.jclouds.mezeo.pcs2.domain.FileMetadata; import org.jclouds.mezeo.pcs2.domain.PCSFile; import org.jclouds.mezeo.pcs2.functions.FindIdInContainerList; import org.jclouds.mezeo.pcs2.functions.FindIdInFileList; -import org.jclouds.mezeo.pcs2.functions.Key; import org.jclouds.mezeo.pcs2.reference.PCSConstants; import com.google.common.base.Function; diff --git a/mezeo/pcs2/core/src/main/java/org/jclouds/mezeo/pcs2/binders/CreateContainerBinder.java b/mezeo/pcs2/core/src/main/java/org/jclouds/mezeo/pcs2/decorators/AddContainerNameAsXmlEntity.java similarity index 85% rename from mezeo/pcs2/core/src/main/java/org/jclouds/mezeo/pcs2/binders/CreateContainerBinder.java rename to mezeo/pcs2/core/src/main/java/org/jclouds/mezeo/pcs2/decorators/AddContainerNameAsXmlEntity.java index de17d6e36c..31046d3fd7 100644 --- a/mezeo/pcs2/core/src/main/java/org/jclouds/mezeo/pcs2/binders/CreateContainerBinder.java +++ b/mezeo/pcs2/core/src/main/java/org/jclouds/mezeo/pcs2/decorators/AddContainerNameAsXmlEntity.java @@ -21,28 +21,29 @@ * under the License. * ==================================================================== */ -package org.jclouds.mezeo.pcs2.binders; +package org.jclouds.mezeo.pcs2.decorators; import java.util.Collections; import javax.ws.rs.core.HttpHeaders; import org.jclouds.http.HttpRequest; -import org.jclouds.rest.binders.EntityBinder; +import org.jclouds.rest.decorators.RequestDecorator; /** * * @author Adrian Cole * */ -public class CreateContainerBinder implements EntityBinder { +public class AddContainerNameAsXmlEntity implements RequestDecorator { - public void addEntityToRequest(Object toBind, HttpRequest request) { + public HttpRequest decorateRequest(HttpRequest request, Object toBind) { String container = String.format("%s", toBind); request.setEntity(container); request.getHeaders().replaceValues(HttpHeaders.CONTENT_LENGTH, Collections.singletonList(container.getBytes().length + "")); request.getHeaders().replaceValues(HttpHeaders.CONTENT_TYPE, Collections.singletonList("application/vnd.csp.container-info+xml")); + return request; } } diff --git a/mezeo/pcs2/core/src/main/java/org/jclouds/mezeo/pcs2/binders/BlockBinder.java b/mezeo/pcs2/core/src/main/java/org/jclouds/mezeo/pcs2/decorators/AddDataAndLength.java similarity index 61% rename from mezeo/pcs2/core/src/main/java/org/jclouds/mezeo/pcs2/binders/BlockBinder.java rename to mezeo/pcs2/core/src/main/java/org/jclouds/mezeo/pcs2/decorators/AddDataAndLength.java index 5be98f9ac1..34972dbfa5 100644 --- a/mezeo/pcs2/core/src/main/java/org/jclouds/mezeo/pcs2/binders/BlockBinder.java +++ b/mezeo/pcs2/core/src/main/java/org/jclouds/mezeo/pcs2/decorators/AddDataAndLength.java @@ -1,4 +1,4 @@ -package org.jclouds.mezeo.pcs2.binders; +package org.jclouds.mezeo.pcs2.decorators; import static com.google.common.base.Preconditions.checkNotNull; @@ -6,13 +6,14 @@ import javax.ws.rs.core.HttpHeaders; import org.jclouds.blobstore.domain.Blob; import org.jclouds.http.HttpRequest; -import org.jclouds.rest.binders.EntityBinder; +import org.jclouds.rest.decorators.RequestDecorator; -public class BlockBinder implements EntityBinder { +public class AddDataAndLength implements RequestDecorator { - public void addEntityToRequest(Object entity, HttpRequest request) { + public HttpRequest decorateRequest(HttpRequest request, Object entity) { Blob object = (Blob) entity; request.setEntity(checkNotNull(object.getData(), "object.getContent()")); request.getHeaders().put(HttpHeaders.CONTENT_LENGTH, object.getMetadata().getSize() + ""); + return request; } } diff --git a/mezeo/pcs2/core/src/main/java/org/jclouds/mezeo/pcs2/binders/CreateFileBinder.java b/mezeo/pcs2/core/src/main/java/org/jclouds/mezeo/pcs2/decorators/AddFileInfoAsXmlEntity.java similarity index 80% rename from mezeo/pcs2/core/src/main/java/org/jclouds/mezeo/pcs2/binders/CreateFileBinder.java rename to mezeo/pcs2/core/src/main/java/org/jclouds/mezeo/pcs2/decorators/AddFileInfoAsXmlEntity.java index c03482a715..6b865314b7 100644 --- a/mezeo/pcs2/core/src/main/java/org/jclouds/mezeo/pcs2/binders/CreateFileBinder.java +++ b/mezeo/pcs2/core/src/main/java/org/jclouds/mezeo/pcs2/decorators/AddFileInfoAsXmlEntity.java @@ -21,28 +21,28 @@ * under the License. * ==================================================================== */ -package org.jclouds.mezeo.pcs2.binders; +package org.jclouds.mezeo.pcs2.decorators; import java.util.Collections; import javax.ws.rs.core.HttpHeaders; import org.jclouds.blobstore.domain.Blob; +import org.jclouds.blobstore.domain.Key; +import org.jclouds.blobstore.util.BlobStoreUtils; import org.jclouds.http.HttpRequest; -import org.jclouds.mezeo.pcs2.functions.Key; -import org.jclouds.mezeo.pcs2.util.PCSUtils; -import org.jclouds.rest.binders.EntityBinder; +import org.jclouds.rest.decorators.RequestDecorator; /** * * @author Adrian Cole * */ -public class CreateFileBinder implements EntityBinder { +public class AddFileInfoAsXmlEntity implements RequestDecorator { - public void addEntityToRequest(Object toBind, HttpRequest request) { + public HttpRequest decorateRequest(HttpRequest request, Object toBind) { Blob blob = (Blob) toBind; - String bareKey = PCSUtils.parseKey(new Key("trash", blob.getKey())).getKey(); + String bareKey = BlobStoreUtils.parseKey(new Key("trash", blob.getKey())).getKey(); String file = String.format( "%s%sfalse", bareKey, blob.getMetadata().getContentType()); @@ -51,5 +51,6 @@ public class CreateFileBinder implements EntityBinder { Collections.singletonList(file.getBytes().length + "")); request.getHeaders().replaceValues(HttpHeaders.CONTENT_TYPE, Collections.singletonList("application/vnd.csp.file-info+xml")); + return request; } } diff --git a/mezeo/pcs2/core/src/main/java/org/jclouds/mezeo/pcs2/functions/AddEntryIntoMultiMap.java b/mezeo/pcs2/core/src/main/java/org/jclouds/mezeo/pcs2/functions/AddEntryIntoMultiMap.java index 24f13b2cb4..b2d32a2ebe 100644 --- a/mezeo/pcs2/core/src/main/java/org/jclouds/mezeo/pcs2/functions/AddEntryIntoMultiMap.java +++ b/mezeo/pcs2/core/src/main/java/org/jclouds/mezeo/pcs2/functions/AddEntryIntoMultiMap.java @@ -9,7 +9,7 @@ import javax.inject.Inject; import org.jclouds.http.HttpRequest; import org.jclouds.http.HttpResponse; import org.jclouds.http.functions.ReturnStringIf200; -import org.jclouds.rest.RestContext; +import org.jclouds.rest.InvocationContext; import com.google.common.base.Function; import com.google.common.collect.Multimap; @@ -18,7 +18,7 @@ import com.google.common.collect.Multimap; * * @author Adrian Cole */ -public class AddEntryIntoMultiMap implements Function, RestContext { +public class AddEntryIntoMultiMap implements Function, InvocationContext { ReturnStringIf200 returnIf200; @Inject diff --git a/mezeo/pcs2/core/src/main/java/org/jclouds/mezeo/pcs2/functions/AddMetadataAndParseResourceIdIntoBytes.java b/mezeo/pcs2/core/src/main/java/org/jclouds/mezeo/pcs2/functions/AddMetadataAndParseResourceIdIntoBytes.java index 667e0641e5..2752fb2d7c 100644 --- a/mezeo/pcs2/core/src/main/java/org/jclouds/mezeo/pcs2/functions/AddMetadataAndParseResourceIdIntoBytes.java +++ b/mezeo/pcs2/core/src/main/java/org/jclouds/mezeo/pcs2/functions/AddMetadataAndParseResourceIdIntoBytes.java @@ -38,6 +38,7 @@ import javax.inject.Inject; import javax.inject.Named; import org.apache.commons.io.IOUtils; +import org.jclouds.blobstore.domain.Key; import org.jclouds.blobstore.internal.BlobRuntimeException; import org.jclouds.blobstore.reference.BlobStoreConstants; import org.jclouds.http.HttpRequest; @@ -46,7 +47,7 @@ import org.jclouds.logging.Logger; import org.jclouds.mezeo.pcs2.PCSUtil; import org.jclouds.mezeo.pcs2.domain.PCSFile; import org.jclouds.mezeo.pcs2.util.PCSUtils; -import org.jclouds.rest.RestContext; +import org.jclouds.rest.InvocationContext; import org.jclouds.util.Utils; import com.google.common.base.Function; @@ -58,7 +59,7 @@ import com.google.common.collect.Sets; * @author Adrian Cole */ public class AddMetadataAndParseResourceIdIntoBytes implements Function, - RestContext { + InvocationContext { private final PCSUtil util; private final ConcurrentMap fileCache; diff --git a/mezeo/pcs2/core/src/main/java/org/jclouds/mezeo/pcs2/functions/AssembleBlobFromContentAndMetadataCache.java b/mezeo/pcs2/core/src/main/java/org/jclouds/mezeo/pcs2/functions/AssembleBlobFromContentAndMetadataCache.java index 94c253b20b..e1f1fdf377 100644 --- a/mezeo/pcs2/core/src/main/java/org/jclouds/mezeo/pcs2/functions/AssembleBlobFromContentAndMetadataCache.java +++ b/mezeo/pcs2/core/src/main/java/org/jclouds/mezeo/pcs2/functions/AssembleBlobFromContentAndMetadataCache.java @@ -27,12 +27,13 @@ import java.util.concurrent.ConcurrentMap; import javax.inject.Inject; +import org.jclouds.blobstore.domain.Key; import org.jclouds.blobstore.functions.ParseContentTypeFromHeaders; import org.jclouds.http.HttpRequest; import org.jclouds.http.HttpResponse; import org.jclouds.mezeo.pcs2.domain.FileMetadata; import org.jclouds.mezeo.pcs2.domain.PCSFile; -import org.jclouds.rest.RestContext; +import org.jclouds.rest.InvocationContext; import com.google.common.base.Function; @@ -43,7 +44,7 @@ import com.google.common.base.Function; * @author Adrian Cole */ public class AssembleBlobFromContentAndMetadataCache implements Function, - RestContext { + InvocationContext { private final ConcurrentMap cache; private HttpRequest request; diff --git a/mezeo/pcs2/core/src/main/java/org/jclouds/mezeo/pcs2/functions/ContainerAndFileNameToResourceId.java b/mezeo/pcs2/core/src/main/java/org/jclouds/mezeo/pcs2/functions/ContainerAndFileNameToResourceId.java index 85346687e8..9ed007f333 100644 --- a/mezeo/pcs2/core/src/main/java/org/jclouds/mezeo/pcs2/functions/ContainerAndFileNameToResourceId.java +++ b/mezeo/pcs2/core/src/main/java/org/jclouds/mezeo/pcs2/functions/ContainerAndFileNameToResourceId.java @@ -34,6 +34,7 @@ import javax.inject.Singleton; import org.jclouds.blobstore.ContainerNotFoundException; import org.jclouds.blobstore.KeyNotFoundException; +import org.jclouds.blobstore.domain.Key; import org.jclouds.util.Utils; import com.google.common.base.Function; diff --git a/mezeo/pcs2/core/src/main/java/org/jclouds/mezeo/pcs2/functions/CreateSubFolderIfNotExistsAndGetResourceId.java b/mezeo/pcs2/core/src/main/java/org/jclouds/mezeo/pcs2/functions/CreateSubFolderIfNotExistsAndGetResourceId.java index e325cc6e1b..b5e25950d6 100644 --- a/mezeo/pcs2/core/src/main/java/org/jclouds/mezeo/pcs2/functions/CreateSubFolderIfNotExistsAndGetResourceId.java +++ b/mezeo/pcs2/core/src/main/java/org/jclouds/mezeo/pcs2/functions/CreateSubFolderIfNotExistsAndGetResourceId.java @@ -40,8 +40,10 @@ import javax.inject.Singleton; import org.jclouds.blobstore.ContainerNotFoundException; import org.jclouds.blobstore.domain.Blob; +import org.jclouds.blobstore.domain.Key; import org.jclouds.blobstore.internal.BlobRuntimeException; import org.jclouds.blobstore.reference.BlobStoreConstants; +import org.jclouds.blobstore.util.BlobStoreUtils; import org.jclouds.mezeo.pcs2.PCSConnection; import org.jclouds.mezeo.pcs2.domain.ContainerMetadata; import org.jclouds.mezeo.pcs2.endpoints.RootContainer; @@ -85,7 +87,7 @@ public class CreateSubFolderIfNotExistsAndGetResourceId implements Function response = blobStore.listContainers(); URI containerUri; try { - containerUri = urlForNameInListOrCreate(rootContainer, containerTree[0], - response); + containerUri = urlForNameInListOrCreate(rootContainer, containerTree[0], response); } catch (Exception e1) { Utils. rethrowIfRuntimeOrSameType(e1); - throw new BlobRuntimeException("error creating container at: " + containerTree[0], e1); + throw new BlobRuntimeException("error creating container at: " + containerTree[0], + e1); } if (containerTree.length != 1) { for (int i = 1; i < containerTree.length; i++) { diff --git a/mezeo/pcs2/core/src/main/java/org/jclouds/mezeo/pcs2/functions/CreateSubFolderIfNotExistsAndNewFileResource.java b/mezeo/pcs2/core/src/main/java/org/jclouds/mezeo/pcs2/functions/CreateSubFolderIfNotExistsAndNewFileResource.java index c8c8122f68..55bd754386 100644 --- a/mezeo/pcs2/core/src/main/java/org/jclouds/mezeo/pcs2/functions/CreateSubFolderIfNotExistsAndNewFileResource.java +++ b/mezeo/pcs2/core/src/main/java/org/jclouds/mezeo/pcs2/functions/CreateSubFolderIfNotExistsAndNewFileResource.java @@ -38,6 +38,7 @@ import javax.ws.rs.core.UriBuilder; import org.jclouds.blobstore.ContainerNotFoundException; import org.jclouds.blobstore.KeyNotFoundException; +import org.jclouds.blobstore.domain.Key; import org.jclouds.blobstore.internal.BlobRuntimeException; import org.jclouds.blobstore.reference.BlobStoreConstants; import org.jclouds.mezeo.pcs2.PCS; diff --git a/mezeo/pcs2/core/src/main/java/org/jclouds/mezeo/pcs2/functions/FindIdInFileList.java b/mezeo/pcs2/core/src/main/java/org/jclouds/mezeo/pcs2/functions/FindIdInFileList.java index d698c474ef..3a06a7f627 100644 --- a/mezeo/pcs2/core/src/main/java/org/jclouds/mezeo/pcs2/functions/FindIdInFileList.java +++ b/mezeo/pcs2/core/src/main/java/org/jclouds/mezeo/pcs2/functions/FindIdInFileList.java @@ -32,11 +32,12 @@ import javax.inject.Inject; import org.jclouds.blobstore.BlobStore; import org.jclouds.blobstore.ContainerNotFoundException; import org.jclouds.blobstore.KeyNotFoundException; +import org.jclouds.blobstore.domain.Key; +import org.jclouds.blobstore.util.BlobStoreUtils; import org.jclouds.http.HttpException; import org.jclouds.mezeo.pcs2.domain.ContainerMetadata; import org.jclouds.mezeo.pcs2.domain.FileMetadata; import org.jclouds.mezeo.pcs2.domain.PCSFile; -import org.jclouds.mezeo.pcs2.util.PCSUtils; import org.jclouds.util.Utils; import com.google.common.annotations.VisibleForTesting; @@ -51,7 +52,7 @@ public class FindIdInFileList implements Function { } public String apply(Key key) { - key = PCSUtils.parseKey(key); + key = BlobStoreUtils.parseKey(key); SortedSet response; try { response = connection.listBlobs(key.getContainer()).get(10, TimeUnit.SECONDS); diff --git a/mezeo/pcs2/core/src/main/java/org/jclouds/mezeo/pcs2/functions/InvalidateContainerNameCacheAndReturnTrueIf2xx.java b/mezeo/pcs2/core/src/main/java/org/jclouds/mezeo/pcs2/functions/InvalidateContainerNameCacheAndReturnTrueIf2xx.java index c32c2210e1..fd2a3747ce 100644 --- a/mezeo/pcs2/core/src/main/java/org/jclouds/mezeo/pcs2/functions/InvalidateContainerNameCacheAndReturnTrueIf2xx.java +++ b/mezeo/pcs2/core/src/main/java/org/jclouds/mezeo/pcs2/functions/InvalidateContainerNameCacheAndReturnTrueIf2xx.java @@ -30,7 +30,7 @@ import javax.inject.Inject; import org.apache.commons.io.IOUtils; import org.jclouds.http.HttpRequest; import org.jclouds.http.HttpResponse; -import org.jclouds.rest.RestContext; +import org.jclouds.rest.InvocationContext; import com.google.common.base.Function; @@ -40,7 +40,7 @@ import com.google.common.base.Function; * @author Adrian Cole */ public class InvalidateContainerNameCacheAndReturnTrueIf2xx implements Function, - RestContext { + InvocationContext { private final ConcurrentMap cache; private HttpRequest request; private Object[] args; diff --git a/mezeo/pcs2/core/src/main/java/org/jclouds/mezeo/pcs2/functions/InvalidatePCSKeyCacheAndReturnVoidIf2xx.java b/mezeo/pcs2/core/src/main/java/org/jclouds/mezeo/pcs2/functions/InvalidatePCSKeyCacheAndReturnVoidIf2xx.java index 0793b4c250..9e78b167d9 100644 --- a/mezeo/pcs2/core/src/main/java/org/jclouds/mezeo/pcs2/functions/InvalidatePCSKeyCacheAndReturnVoidIf2xx.java +++ b/mezeo/pcs2/core/src/main/java/org/jclouds/mezeo/pcs2/functions/InvalidatePCSKeyCacheAndReturnVoidIf2xx.java @@ -28,10 +28,11 @@ import java.util.concurrent.ConcurrentMap; import javax.inject.Inject; import org.apache.commons.io.IOUtils; +import org.jclouds.blobstore.domain.Key; import org.jclouds.http.HttpRequest; import org.jclouds.http.HttpResponse; import org.jclouds.mezeo.pcs2.domain.FileMetadata; -import org.jclouds.rest.RestContext; +import org.jclouds.rest.InvocationContext; import com.google.common.base.Function; @@ -41,7 +42,7 @@ import com.google.common.base.Function; * @author Adrian Cole */ public class InvalidatePCSKeyCacheAndReturnVoidIf2xx implements Function, - RestContext { + InvocationContext { private final ConcurrentMap cache; private final ConcurrentMap mdCache; private HttpRequest request; diff --git a/mezeo/pcs2/core/src/main/java/org/jclouds/mezeo/pcs2/util/PCSUtils.java b/mezeo/pcs2/core/src/main/java/org/jclouds/mezeo/pcs2/util/PCSUtils.java index 881a817654..68a3a91f96 100644 --- a/mezeo/pcs2/core/src/main/java/org/jclouds/mezeo/pcs2/util/PCSUtils.java +++ b/mezeo/pcs2/core/src/main/java/org/jclouds/mezeo/pcs2/util/PCSUtils.java @@ -26,7 +26,6 @@ package org.jclouds.mezeo.pcs2.util; import java.net.URI; import org.jclouds.http.HttpUtils; -import org.jclouds.mezeo.pcs2.functions.Key; /** * Utilities for PCS connections. @@ -49,17 +48,6 @@ public class PCSUtils { return eTag; } - public static Key parseKey(Key key) { - - if (key.getKey().indexOf('/') != -1) { - String container = key.getContainer() + '/' - + key.getKey().substring(0, key.getKey().lastIndexOf('/')); - String newKey = key.getKey().substring(key.getKey().lastIndexOf('/') + 1); - key = new Key(container.replaceAll("//", "/"), newKey); - } - return key; - } - public static String getContainerId(URI url) { String path = url.getPath(); int indexAfterContainersSlash = path.indexOf("containers/") + "containers/".length(); diff --git a/mezeo/pcs2/core/src/test/java/org/jclouds/mezeo/pcs2/PCSBlobStoreTest.java b/mezeo/pcs2/core/src/test/java/org/jclouds/mezeo/pcs2/PCSBlobStoreTest.java index 6389e3be2a..caddd68155 100644 --- a/mezeo/pcs2/core/src/test/java/org/jclouds/mezeo/pcs2/PCSBlobStoreTest.java +++ b/mezeo/pcs2/core/src/test/java/org/jclouds/mezeo/pcs2/PCSBlobStoreTest.java @@ -54,7 +54,6 @@ import org.jclouds.http.functions.ParseSax; import org.jclouds.http.functions.ReturnTrueIf2xx; import org.jclouds.http.functions.ReturnVoidIf2xx; import org.jclouds.http.options.GetOptions; -import org.jclouds.mezeo.pcs2.binders.PCSFileAsMultipartFormBinderTest; import org.jclouds.mezeo.pcs2.domain.ContainerMetadata; import org.jclouds.mezeo.pcs2.domain.FileMetadata; import org.jclouds.mezeo.pcs2.domain.PCSFile; @@ -67,8 +66,8 @@ import org.jclouds.mezeo.pcs2.functions.InvalidateContainerNameCacheAndReturnTru import org.jclouds.mezeo.pcs2.functions.InvalidatePCSKeyCacheAndReturnVoidIf2xx; import org.jclouds.mezeo.pcs2.functions.ReturnFalseIfContainerNotFound; import org.jclouds.mezeo.pcs2.options.PutBlockOptions; -import org.jclouds.rest.JaxrsAnnotationProcessor; -import org.jclouds.rest.config.JaxrsModule; +import org.jclouds.rest.config.RestModule; +import org.jclouds.rest.internal.RestAnnotationProcessor; import org.jclouds.util.DateService; import org.testng.annotations.BeforeClass; import org.testng.annotations.Test; @@ -298,19 +297,18 @@ public class PCSBlobStoreTest { public void testPutBlob() throws SecurityException, NoSuchMethodException, IOException { Method method = PCSBlobStore.class.getMethod("putBlob", String.class, PCSFile.class); - - HttpRequest httpMethod = processor.createRequest(method, new Object[] { "mycontainer", - PCSFileAsMultipartFormBinderTest.TEST_BLOB }); + PCSFile file = new PCSFile("hello"); + file.setData("wonkers"); + HttpRequest httpMethod = processor + .createRequest(method, new Object[] { "mycontainer", file }); assertEquals(httpMethod.getEndpoint().getHost(), "localhost"); assertEquals(httpMethod.getEndpoint().getPath(), "/files/o/content"); assertEquals(httpMethod.getEndpoint().getQuery(), null); assertEquals(httpMethod.getMethod(), HttpMethod.PUT); assertEquals(httpMethod.getHeaders().size(), 1); assertEquals(httpMethod.getHeaders().get(HttpHeaders.CONTENT_LENGTH), Collections - .singletonList(PCSFileAsMultipartFormBinderTest.TEST_BLOB.getData().toString() - .getBytes().length - + "")); - assertEquals(httpMethod.getEntity(), PCSFileAsMultipartFormBinderTest.TEST_BLOB.getData()); + .singletonList(file.getData().toString().getBytes().length + "")); + assertEquals(httpMethod.getEntity(), file.getData()); assertEquals(processor.createResponseParser(method, httpMethod, null).getClass(), AddMetadataAndParseResourceIdIntoBytes.class); } @@ -419,8 +417,8 @@ public class PCSBlobStoreTest { AddEntryIntoMultiMap.class); } - JaxrsAnnotationProcessor processor; - private JaxrsAnnotationProcessor utilProcessor; + RestAnnotationProcessor processor; + private RestAnnotationProcessor utilProcessor; @BeforeClass void setupFactory() { @@ -459,22 +457,20 @@ public class PCSBlobStoreTest { @SuppressWarnings("unused") @Provides @Singleton - ConcurrentMap giveMap() { - ConcurrentHashMap map = new ConcurrentHashMap(); - map.put( - new org.jclouds.mezeo.pcs2.functions.Key("mycontainer", - "testfile.txt"), "9E4C5AFA-A98B-11DE-8B4C-C3884B4A2DA3"); + ConcurrentMap giveMap() { + ConcurrentHashMap map = new ConcurrentHashMap(); + map.put(new org.jclouds.blobstore.domain.Key("mycontainer", "testfile.txt"), + "9E4C5AFA-A98B-11DE-8B4C-C3884B4A2DA3"); return map; } @SuppressWarnings("unused") @Provides @Singleton - ConcurrentMap giveMap2() { - ConcurrentHashMap map = new ConcurrentHashMap(); - map.put( - new org.jclouds.mezeo.pcs2.functions.Key("mycontainer", - "testfile.txt"), new FileMetadata("testfile.txt")); + ConcurrentMap giveMap2() { + ConcurrentHashMap map = new ConcurrentHashMap(); + map.put(new org.jclouds.blobstore.domain.Key("mycontainer", "testfile.txt"), + new FileMetadata("testfile.txt")); return map; } @@ -494,14 +490,14 @@ public class PCSBlobStoreTest { throws UnsupportedEncodingException { return new BasicAuthentication("foo", "bar"); } - }, new JaxrsModule(), new ExecutorServiceModule(new WithinThreadExecutorService()), + }, new RestModule(), new ExecutorServiceModule(new WithinThreadExecutorService()), new JavaUrlHttpCommandExecutorServiceModule()); processor = injector.getInstance(Key - .get(new TypeLiteral>() { + .get(new TypeLiteral>() { })); utilProcessor = injector.getInstance(Key - .get(new TypeLiteral>() { + .get(new TypeLiteral>() { })); } } diff --git a/mezeo/pcs2/core/src/test/java/org/jclouds/mezeo/pcs2/PCSCloudLiveTest.java b/mezeo/pcs2/core/src/test/java/org/jclouds/mezeo/pcs2/PCSCloudLiveTest.java index 4b824afd90..7e00e2867f 100644 --- a/mezeo/pcs2/core/src/test/java/org/jclouds/mezeo/pcs2/PCSCloudLiveTest.java +++ b/mezeo/pcs2/core/src/test/java/org/jclouds/mezeo/pcs2/PCSCloudLiveTest.java @@ -37,7 +37,7 @@ import org.jclouds.http.config.JavaUrlHttpCommandExecutorServiceModule; import org.jclouds.http.filters.BasicAuthentication; import org.jclouds.mezeo.pcs2.PCSCloud.Response; import org.jclouds.rest.RestClientFactory; -import org.jclouds.rest.config.JaxrsModule; +import org.jclouds.rest.config.RestModule; import org.testng.annotations.BeforeClass; import org.testng.annotations.Test; @@ -97,7 +97,7 @@ public class PCSCloudLiveTest { protected PCSCloud provideCloud(RestClientFactory factory) { return factory.create(PCSCloud.class); } - }, new JaxrsModule(), new ExecutorServiceModule(new WithinThreadExecutorService()), + }, new RestModule(), new ExecutorServiceModule(new WithinThreadExecutorService()), new JavaUrlHttpCommandExecutorServiceModule()); } } diff --git a/mezeo/pcs2/core/src/test/java/org/jclouds/mezeo/pcs2/PCSConnectionTest.java b/mezeo/pcs2/core/src/test/java/org/jclouds/mezeo/pcs2/PCSConnectionTest.java index a4f8c26eb4..6f1a8bd259 100644 --- a/mezeo/pcs2/core/src/test/java/org/jclouds/mezeo/pcs2/PCSConnectionTest.java +++ b/mezeo/pcs2/core/src/test/java/org/jclouds/mezeo/pcs2/PCSConnectionTest.java @@ -39,6 +39,7 @@ import javax.inject.Singleton; import javax.ws.rs.HttpMethod; import javax.ws.rs.core.HttpHeaders; +import org.jclouds.blobstore.decorators.AddBlobEntityAsMultipartFormTest; import org.jclouds.blobstore.functions.ReturnVoidOnNotFoundOr404; import org.jclouds.concurrent.WithinThreadExecutorService; import org.jclouds.concurrent.config.ExecutorServiceModule; @@ -49,12 +50,11 @@ import org.jclouds.http.functions.ParseSax; import org.jclouds.http.functions.ParseURIList; import org.jclouds.http.functions.ReturnInputStream; import org.jclouds.http.functions.ReturnVoidIf2xx; -import org.jclouds.mezeo.pcs2.binders.PCSFileAsMultipartFormBinderTest; import org.jclouds.mezeo.pcs2.domain.FileMetadata; import org.jclouds.mezeo.pcs2.domain.PCSFile; import org.jclouds.mezeo.pcs2.endpoints.RootContainer; -import org.jclouds.rest.JaxrsAnnotationProcessor; -import org.jclouds.rest.config.JaxrsModule; +import org.jclouds.rest.config.RestModule; +import org.jclouds.rest.internal.RestAnnotationProcessor; import org.jclouds.util.Utils; import org.testng.annotations.BeforeClass; import org.testng.annotations.Test; @@ -165,19 +165,19 @@ public class PCSConnectionTest { HttpRequest httpMethod = processor.createRequest(method, new Object[] { URI.create("http://localhost/mycontainer"), - PCSFileAsMultipartFormBinderTest.TEST_BLOB }); + AddBlobEntityAsMultipartFormTest.TEST_BLOB }); assertEquals(httpMethod.getEndpoint().getHost(), "localhost"); assertEquals(httpMethod.getEndpoint().getPath(), "/mycontainer/contents"); assertEquals(httpMethod.getEndpoint().getQuery(), null); assertEquals(httpMethod.getMethod(), HttpMethod.POST); assertEquals(httpMethod.getHeaders().size(), 2); assertEquals(httpMethod.getHeaders().get(HttpHeaders.CONTENT_LENGTH), Collections - .singletonList(PCSFileAsMultipartFormBinderTest.EXPECTS.length() + "")); + .singletonList(AddBlobEntityAsMultipartFormTest.EXPECTS.length() + "")); assertEquals(httpMethod.getHeaders().get(HttpHeaders.CONTENT_TYPE), Collections .singletonList("multipart/form-data; boundary=" - + PCSFileAsMultipartFormBinderTest.BOUNDRY)); + + AddBlobEntityAsMultipartFormTest.BOUNDRY)); assertEquals(Utils.toStringAndClose((InputStream) httpMethod.getEntity()), - PCSFileAsMultipartFormBinderTest.EXPECTS); + AddBlobEntityAsMultipartFormTest.EXPECTS); assertEquals(processor.createResponseParser(method, httpMethod, null).getClass(), ParseURIList.class); } @@ -212,7 +212,7 @@ public class PCSConnectionTest { ReturnVoidOnNotFoundOr404.class); } - JaxrsAnnotationProcessor processor; + RestAnnotationProcessor processor; @BeforeClass void setupFactory() { @@ -248,22 +248,20 @@ public class PCSConnectionTest { @SuppressWarnings("unused") @Provides @Singleton - ConcurrentMap giveMap() { - ConcurrentHashMap map = new ConcurrentHashMap(); - map.put( - new org.jclouds.mezeo.pcs2.functions.Key("mycontainer", - "testfile.txt"), "9E4C5AFA-A98B-11DE-8B4C-C3884B4A2DA3"); + ConcurrentMap giveMap() { + ConcurrentHashMap map = new ConcurrentHashMap(); + map.put(new org.jclouds.blobstore.domain.Key("mycontainer", "testfile.txt"), + "9E4C5AFA-A98B-11DE-8B4C-C3884B4A2DA3"); return map; } @SuppressWarnings("unused") @Provides @Singleton - ConcurrentMap giveMap2() { - ConcurrentHashMap map = new ConcurrentHashMap(); - map.put( - new org.jclouds.mezeo.pcs2.functions.Key("mycontainer", - "testfile.txt"), new FileMetadata("testfile.txt")); + ConcurrentMap giveMap2() { + ConcurrentHashMap map = new ConcurrentHashMap(); + map.put(new org.jclouds.blobstore.domain.Key("mycontainer", "testfile.txt"), + new FileMetadata("testfile.txt")); return map; } @@ -283,11 +281,11 @@ public class PCSConnectionTest { throws UnsupportedEncodingException { return new BasicAuthentication("foo", "bar"); } - }, new JaxrsModule(), new ExecutorServiceModule(new WithinThreadExecutorService()), + }, new RestModule(), new ExecutorServiceModule(new WithinThreadExecutorService()), new JavaUrlHttpCommandExecutorServiceModule()); processor = injector.getInstance(Key - .get(new TypeLiteral>() { + .get(new TypeLiteral>() { })); } } diff --git a/mezeo/pcs2/core/src/test/java/org/jclouds/mezeo/pcs2/binders/CreateContainerBinderTest.java b/mezeo/pcs2/core/src/test/java/org/jclouds/mezeo/pcs2/decorators/AddContainerNameAsXmlEntityTest.java similarity index 83% rename from mezeo/pcs2/core/src/test/java/org/jclouds/mezeo/pcs2/binders/CreateContainerBinderTest.java rename to mezeo/pcs2/core/src/test/java/org/jclouds/mezeo/pcs2/decorators/AddContainerNameAsXmlEntityTest.java index 898af16861..6f20e06955 100644 --- a/mezeo/pcs2/core/src/test/java/org/jclouds/mezeo/pcs2/binders/CreateContainerBinderTest.java +++ b/mezeo/pcs2/core/src/test/java/org/jclouds/mezeo/pcs2/decorators/AddContainerNameAsXmlEntityTest.java @@ -21,7 +21,7 @@ * under the License. * ==================================================================== */ -package org.jclouds.mezeo.pcs2.binders; +package org.jclouds.mezeo.pcs2.decorators; import static org.testng.Assert.assertEquals; @@ -33,17 +33,17 @@ import org.jclouds.http.HttpRequest; import org.testng.annotations.Test; /** - * Tests behavior of {@code ParseFlavorListFromGsonResponseTest} + * Tests behavior of {@code AddContainerNameAsXmlEntity} * * @author Adrian Cole */ -@Test(groups = "unit", testName = "pcs2.CreateContainerBinderTest") -public class CreateContainerBinderTest { +@Test(groups = "unit", testName = "pcs2.AddContainerNameAsXmlEntityTest") +public class AddContainerNameAsXmlEntityTest { public void test() { - CreateContainerBinder binder = new CreateContainerBinder(); + AddContainerNameAsXmlEntity binder = new AddContainerNameAsXmlEntity(); HttpRequest request = new HttpRequest("GET", URI.create("http://localhost")); - binder.addEntityToRequest("foo", request); + binder.decorateRequest(request, "foo"); assertEquals(request.getEntity(), "foo"); assertEquals(request.getFirstHeaderOrNull(HttpHeaders.CONTENT_LENGTH), "foo".getBytes().length + ""); diff --git a/mezeo/pcs2/core/src/test/java/org/jclouds/mezeo/pcs2/binders/CreateFileBinderTest.java b/mezeo/pcs2/core/src/test/java/org/jclouds/mezeo/pcs2/decorators/AddFileInfoAsXmlEntityTest.java similarity index 86% rename from mezeo/pcs2/core/src/test/java/org/jclouds/mezeo/pcs2/binders/CreateFileBinderTest.java rename to mezeo/pcs2/core/src/test/java/org/jclouds/mezeo/pcs2/decorators/AddFileInfoAsXmlEntityTest.java index d0d8d85e6f..9c2581f331 100644 --- a/mezeo/pcs2/core/src/test/java/org/jclouds/mezeo/pcs2/binders/CreateFileBinderTest.java +++ b/mezeo/pcs2/core/src/test/java/org/jclouds/mezeo/pcs2/decorators/AddFileInfoAsXmlEntityTest.java @@ -21,7 +21,7 @@ * under the License. * ==================================================================== */ -package org.jclouds.mezeo.pcs2.binders; +package org.jclouds.mezeo.pcs2.decorators; import static org.testng.Assert.assertEquals; @@ -34,18 +34,18 @@ import org.jclouds.mezeo.pcs2.domain.PCSFile; import org.testng.annotations.Test; /** - * Tests behavior of {@code CreateFileBinder} + * Tests behavior of {@code AddFileInfoAsXmlEntity} * * @author Adrian Cole */ -@Test(groups = "unit", testName = "pcs2.CreateFileBinderTest") -public class CreateFileBinderTest { +@Test(groups = "unit", testName = "pcs2.AddFileInfoAsXmlEntityTest") +public class AddFileInfoAsXmlEntityTest { public void test() { - CreateFileBinder binder = new CreateFileBinder(); + AddFileInfoAsXmlEntity binder = new AddFileInfoAsXmlEntity(); HttpRequest request = new HttpRequest("GET", URI.create("http://localhost")); PCSFile file = new PCSFile("foo"); - binder.addEntityToRequest(file, request); + binder.decorateRequest(request, file); assertEquals( request.getEntity(), "fooapplication/octet-streamfalse"); @@ -58,13 +58,12 @@ public class CreateFileBinderTest { "application/vnd.csp.file-info+xml"); } - - + public void testCompound() { - CreateFileBinder binder = new CreateFileBinder(); + AddFileInfoAsXmlEntity binder = new AddFileInfoAsXmlEntity(); HttpRequest request = new HttpRequest("GET", URI.create("http://localhost")); PCSFile file = new PCSFile("subdir/foo"); - binder.addEntityToRequest(file, request); + binder.decorateRequest(request, file); assertEquals( request.getEntity(), "fooapplication/octet-streamfalse"); diff --git a/mezeo/pcs2/core/src/test/java/org/jclouds/mezeo/pcs2/functions/AddMetadataAndParseResourceIdIntoBytesTest.java b/mezeo/pcs2/core/src/test/java/org/jclouds/mezeo/pcs2/functions/AddMetadataAndParseResourceIdIntoBytesTest.java index a199656c9d..55f2715492 100644 --- a/mezeo/pcs2/core/src/test/java/org/jclouds/mezeo/pcs2/functions/AddMetadataAndParseResourceIdIntoBytesTest.java +++ b/mezeo/pcs2/core/src/test/java/org/jclouds/mezeo/pcs2/functions/AddMetadataAndParseResourceIdIntoBytesTest.java @@ -38,12 +38,13 @@ import java.util.concurrent.Future; import javax.ws.rs.ext.RuntimeDelegate; import org.apache.commons.io.IOUtils; +import org.jclouds.blobstore.domain.Key; import org.jclouds.http.HttpRequest; import org.jclouds.http.HttpResponse; import org.jclouds.http.HttpUtils; import org.jclouds.mezeo.pcs2.PCSUtil; import org.jclouds.mezeo.pcs2.domain.PCSFile; -import org.jclouds.rest.RuntimeDelegateImpl; +import org.jclouds.rest.internal.RuntimeDelegateImpl; import org.testng.annotations.BeforeClass; import org.testng.annotations.Test; diff --git a/mezeo/pcs2/core/src/test/java/org/jclouds/mezeo/pcs2/functions/AssembleBlobFromBlobMetadataCallTest.java b/mezeo/pcs2/core/src/test/java/org/jclouds/mezeo/pcs2/functions/AssembleBlobFromBlobMetadataCallTest.java index c418aed500..85a4e84cb2 100644 --- a/mezeo/pcs2/core/src/test/java/org/jclouds/mezeo/pcs2/functions/AssembleBlobFromBlobMetadataCallTest.java +++ b/mezeo/pcs2/core/src/test/java/org/jclouds/mezeo/pcs2/functions/AssembleBlobFromBlobMetadataCallTest.java @@ -31,6 +31,7 @@ import static org.testng.Assert.assertEquals; import java.io.InputStream; import java.util.concurrent.ConcurrentMap; +import org.jclouds.blobstore.domain.Key; import org.jclouds.http.HttpException; import org.jclouds.http.HttpResponse; import org.jclouds.mezeo.pcs2.domain.FileMetadata; diff --git a/mezeo/pcs2/core/src/test/java/org/jclouds/mezeo/pcs2/util/PCSUtilsTest.java b/mezeo/pcs2/core/src/test/java/org/jclouds/mezeo/pcs2/util/PCSUtilsTest.java index 6993bb0ee6..3117a96e78 100644 --- a/mezeo/pcs2/core/src/test/java/org/jclouds/mezeo/pcs2/util/PCSUtilsTest.java +++ b/mezeo/pcs2/core/src/test/java/org/jclouds/mezeo/pcs2/util/PCSUtilsTest.java @@ -28,7 +28,6 @@ import static org.testng.Assert.assertEquals; import java.net.URI; import org.jclouds.http.HttpUtils; -import org.jclouds.mezeo.pcs2.functions.Key; import org.testng.annotations.Test; /** @@ -45,17 +44,4 @@ public class PCSUtilsTest { .create("http://localhost/contents/7F143552-AAF5-11DE-BBB0-0BC388ED913B")); assertEquals(eTag, expected); } - - public void testParseKey() { - Key key = PCSUtils.parseKey(new Key("container", "key")); - assertEquals(key.getContainer(), "container"); - assertEquals(key.getKey(), "key"); - key = PCSUtils.parseKey(new Key("container", "container/key")); - assertEquals(key.getContainer(), "container/container"); - assertEquals(key.getKey(), "key"); - key = PCSUtils.parseKey(new Key("container", "/container/key")); - assertEquals(key.getContainer(), "container/container"); - assertEquals(key.getKey(), "key"); - - } } diff --git a/rackspace/cloudfiles/core/src/main/java/org/jclouds/rackspace/cloudfiles/CloudFilesBlobStore.java b/rackspace/cloudfiles/core/src/main/java/org/jclouds/rackspace/cloudfiles/CloudFilesBlobStore.java index 35380e2890..e406bb054b 100644 --- a/rackspace/cloudfiles/core/src/main/java/org/jclouds/rackspace/cloudfiles/CloudFilesBlobStore.java +++ b/rackspace/cloudfiles/core/src/main/java/org/jclouds/rackspace/cloudfiles/CloudFilesBlobStore.java @@ -35,7 +35,7 @@ import javax.ws.rs.Path; import javax.ws.rs.PathParam; import org.jclouds.blobstore.BlobStore; -import org.jclouds.blobstore.binders.BlobBinder; +import org.jclouds.blobstore.decorators.AddBlobEntity; import org.jclouds.blobstore.domain.Blob; import org.jclouds.blobstore.domain.BlobMetadata; import org.jclouds.blobstore.functions.BlobKey; @@ -53,14 +53,14 @@ import org.jclouds.rackspace.cloudfiles.functions.ParseObjectFromHeadersAndHttpC import org.jclouds.rackspace.cloudfiles.functions.ParseObjectMetadataFromHeaders; import org.jclouds.rackspace.cloudfiles.options.ListContainerOptions; import org.jclouds.rackspace.filters.AuthenticateRequest; -import org.jclouds.rest.Endpoint; -import org.jclouds.rest.EntityParam; -import org.jclouds.rest.ExceptionParser; -import org.jclouds.rest.ParamParser; -import org.jclouds.rest.QueryParams; -import org.jclouds.rest.RequestFilters; -import org.jclouds.rest.ResponseParser; -import org.jclouds.rest.SkipEncoding; +import org.jclouds.rest.annotations.DecoratorParam; +import org.jclouds.rest.annotations.Endpoint; +import org.jclouds.rest.annotations.ExceptionParser; +import org.jclouds.rest.annotations.ParamParser; +import org.jclouds.rest.annotations.QueryParams; +import org.jclouds.rest.annotations.RequestFilters; +import org.jclouds.rest.annotations.ResponseParser; +import org.jclouds.rest.annotations.SkipEncoding; /** * Provides access to Cloud Files via their REST API. @@ -113,7 +113,7 @@ public interface CloudFilesBlobStore extends @ResponseParser(ParseETagHeader.class) Future putBlob( @PathParam("container") String container, - @PathParam("key") @ParamParser(BlobKey.class) @EntityParam(BlobBinder.class) Blob object); + @PathParam("key") @ParamParser(BlobKey.class) @DecoratorParam(AddBlobEntity.class) Blob object); @GET @ResponseParser(ParseObjectFromHeadersAndHttpContent.class) diff --git a/rackspace/cloudfiles/core/src/main/java/org/jclouds/rackspace/cloudfiles/CloudFilesConnection.java b/rackspace/cloudfiles/core/src/main/java/org/jclouds/rackspace/cloudfiles/CloudFilesConnection.java index 8e3cf09ad2..0688784fad 100644 --- a/rackspace/cloudfiles/core/src/main/java/org/jclouds/rackspace/cloudfiles/CloudFilesConnection.java +++ b/rackspace/cloudfiles/core/src/main/java/org/jclouds/rackspace/cloudfiles/CloudFilesConnection.java @@ -36,8 +36,8 @@ import javax.ws.rs.PUT; import javax.ws.rs.Path; import javax.ws.rs.PathParam; -import org.jclouds.blobstore.binders.BlobBinder; -import org.jclouds.blobstore.binders.UserMetadataBinder; +import org.jclouds.blobstore.decorators.AddBlobEntity; +import org.jclouds.blobstore.decorators.AddHeadersWithPrefix; import org.jclouds.blobstore.domain.Blob; import org.jclouds.blobstore.domain.BlobMetadata; import org.jclouds.blobstore.functions.BlobKey; @@ -64,15 +64,15 @@ import org.jclouds.rackspace.cloudfiles.options.ListCdnContainerOptions; import org.jclouds.rackspace.cloudfiles.options.ListContainerOptions; import org.jclouds.rackspace.cloudfiles.reference.CloudFilesHeaders; import org.jclouds.rackspace.filters.AuthenticateRequest; -import org.jclouds.rest.Endpoint; -import org.jclouds.rest.EntityParam; -import org.jclouds.rest.ExceptionParser; -import org.jclouds.rest.Headers; -import org.jclouds.rest.ParamParser; -import org.jclouds.rest.QueryParams; -import org.jclouds.rest.RequestFilters; -import org.jclouds.rest.ResponseParser; -import org.jclouds.rest.SkipEncoding; +import org.jclouds.rest.annotations.DecoratorParam; +import org.jclouds.rest.annotations.Endpoint; +import org.jclouds.rest.annotations.ExceptionParser; +import org.jclouds.rest.annotations.Headers; +import org.jclouds.rest.annotations.ParamParser; +import org.jclouds.rest.annotations.QueryParams; +import org.jclouds.rest.annotations.RequestFilters; +import org.jclouds.rest.annotations.ResponseParser; +import org.jclouds.rest.annotations.SkipEncoding; import com.google.common.collect.Multimap; @@ -141,7 +141,7 @@ public interface CloudFilesConnection { @Path("{container}/{key}") boolean setObjectMetadata(@PathParam("container") String container, @PathParam("key") String key, - @EntityParam(UserMetadataBinder.class) Multimap userMetadata); + @DecoratorParam(AddHeadersWithPrefix.class) Multimap userMetadata); @GET @ResponseParser(ParseContainerCDNMetadataListFromGsonResponse.class) @@ -205,7 +205,7 @@ public interface CloudFilesConnection { @ResponseParser(ParseETagHeader.class) Future putObject( @PathParam("container") String container, - @PathParam("key") @ParamParser(BlobKey.class) @EntityParam(BlobBinder.class) Blob object); + @PathParam("key") @ParamParser(BlobKey.class) @DecoratorParam(AddBlobEntity.class) Blob object); @GET @ResponseParser(ParseObjectFromHeadersAndHttpContent.class) diff --git a/rackspace/cloudfiles/core/src/main/java/org/jclouds/rackspace/cloudfiles/binders/CFObjectBinder.java b/rackspace/cloudfiles/core/src/main/java/org/jclouds/rackspace/cloudfiles/decorators/AddCFObjectEntity.java similarity index 85% rename from rackspace/cloudfiles/core/src/main/java/org/jclouds/rackspace/cloudfiles/binders/CFObjectBinder.java rename to rackspace/cloudfiles/core/src/main/java/org/jclouds/rackspace/cloudfiles/decorators/AddCFObjectEntity.java index f39cb5d355..9c4fc3d06d 100644 --- a/rackspace/cloudfiles/core/src/main/java/org/jclouds/rackspace/cloudfiles/binders/CFObjectBinder.java +++ b/rackspace/cloudfiles/core/src/main/java/org/jclouds/rackspace/cloudfiles/decorators/AddCFObjectEntity.java @@ -21,28 +21,27 @@ * under the License. * ==================================================================== */ -package org.jclouds.rackspace.cloudfiles.binders; +package org.jclouds.rackspace.cloudfiles.decorators; import static com.google.common.base.Preconditions.checkArgument; import static org.jclouds.blobstore.reference.BlobStoreConstants.PROPERTY_USER_METADATA_PREFIX; +import javax.inject.Inject; +import javax.inject.Named; import javax.ws.rs.core.HttpHeaders; -import org.jclouds.blobstore.binders.BlobBinder; +import org.jclouds.blobstore.decorators.AddBlobEntity; import org.jclouds.blobstore.domain.Blob; import org.jclouds.http.HttpRequest; import org.jclouds.http.HttpUtils; -import javax.inject.Inject; -import javax.inject.Named; - -public class CFObjectBinder extends BlobBinder { +public class AddCFObjectEntity extends AddBlobEntity { @Inject - public CFObjectBinder(@Named(PROPERTY_USER_METADATA_PREFIX) String metadataPrefix) { + public AddCFObjectEntity(@Named(PROPERTY_USER_METADATA_PREFIX) String metadataPrefix) { super(metadataPrefix); } - public void addEntityToRequest(Object entity, HttpRequest request) { + public HttpRequest decorateRequest(HttpRequest request, Object entity) { Blob object = (Blob) entity; if (object.getMetadata().getSize() >= 0) { checkArgument(object.getContentLength() <= 5 * 1024 * 1024 * 1024, @@ -59,6 +58,6 @@ public class CFObjectBinder extends BlobBinder { request.getHeaders().put(HttpHeaders.ETAG, HttpUtils.toBase64String(object.getMetadata().getContentMD5())); } - super.addEntityToRequest(entity, request); + return super.decorateRequest(request, entity); } } diff --git a/rackspace/cloudservers/core/src/main/java/org/jclouds/rackspace/cloudservers/CloudServersConnection.java b/rackspace/cloudservers/core/src/main/java/org/jclouds/rackspace/cloudservers/CloudServersConnection.java index e236aad46c..01f2d8c47b 100755 --- a/rackspace/cloudservers/core/src/main/java/org/jclouds/rackspace/cloudservers/CloudServersConnection.java +++ b/rackspace/cloudservers/core/src/main/java/org/jclouds/rackspace/cloudservers/CloudServersConnection.java @@ -37,15 +37,15 @@ import javax.ws.rs.PathParam; import org.jclouds.http.functions.ReturnFalseOn404; import org.jclouds.rackspace.CloudServers; -import org.jclouds.rackspace.cloudservers.binders.BackupScheduleBinder; -import org.jclouds.rackspace.cloudservers.binders.ChangeAdminPassBinder; -import org.jclouds.rackspace.cloudservers.binders.ChangeServerNameBinder; -import org.jclouds.rackspace.cloudservers.binders.ConfirmResizeBinder; -import org.jclouds.rackspace.cloudservers.binders.CreateImageBinder; -import org.jclouds.rackspace.cloudservers.binders.RebootTypeBinder; -import org.jclouds.rackspace.cloudservers.binders.ResizeBinder; -import org.jclouds.rackspace.cloudservers.binders.RevertResizeBinder; -import org.jclouds.rackspace.cloudservers.binders.ShareIpBinder; +import org.jclouds.rackspace.cloudservers.decorators.AddBackupScheduleAsJsonEntity; +import org.jclouds.rackspace.cloudservers.decorators.AddAdminPassAsJsonEntity; +import org.jclouds.rackspace.cloudservers.decorators.AddServerNameAsJsonEntity; +import org.jclouds.rackspace.cloudservers.decorators.AddConfirmResizeAsJsonEntity; +import org.jclouds.rackspace.cloudservers.decorators.AddCreateImageAsJsonEntity; +import org.jclouds.rackspace.cloudservers.decorators.AddRebootTypeAsJsonEntity; +import org.jclouds.rackspace.cloudservers.decorators.AddResizeFlavorAsJsonEntity; +import org.jclouds.rackspace.cloudservers.decorators.AddRevertResizeAsJsonEntity; +import org.jclouds.rackspace.cloudservers.decorators.AddSharedIpGroupAsJsonEntity; import org.jclouds.rackspace.cloudservers.domain.Addresses; import org.jclouds.rackspace.cloudservers.domain.BackupSchedule; import org.jclouds.rackspace.cloudservers.domain.Flavor; @@ -74,16 +74,16 @@ import org.jclouds.rackspace.cloudservers.options.CreateSharedIpGroupOptions; import org.jclouds.rackspace.cloudservers.options.ListOptions; import org.jclouds.rackspace.cloudservers.options.RebuildServerOptions; import org.jclouds.rackspace.filters.AuthenticateRequest; -import org.jclouds.rest.Endpoint; -import org.jclouds.rest.EntityParam; -import org.jclouds.rest.ExceptionParser; -import org.jclouds.rest.MapBinder; -import org.jclouds.rest.MapEntityParam; -import org.jclouds.rest.ParamParser; -import org.jclouds.rest.QueryParams; -import org.jclouds.rest.RequestFilters; -import org.jclouds.rest.ResponseParser; -import org.jclouds.rest.SkipEncoding; +import org.jclouds.rest.annotations.DecoratorParam; +import org.jclouds.rest.annotations.Endpoint; +import org.jclouds.rest.annotations.ExceptionParser; +import org.jclouds.rest.annotations.MapBinder; +import org.jclouds.rest.annotations.MapEntityParam; +import org.jclouds.rest.annotations.ParamParser; +import org.jclouds.rest.annotations.QueryParams; +import org.jclouds.rest.annotations.RequestFilters; +import org.jclouds.rest.annotations.ResponseParser; +import org.jclouds.rest.annotations.SkipEncoding; /** * Provides access to Cloud Servers via their REST API. @@ -170,7 +170,7 @@ public interface CloudServersConnection { // TODO:cloudServersFault (400, 500), serviceUnavailable (503), unauthorized (401), badRequest // (400), badMediaType(415),buildInProgress (409), overLimit (403) boolean rebootServer(@PathParam("id") int id, - @EntityParam(RebootTypeBinder.class) RebootType rebootType); + @DecoratorParam(AddRebootTypeAsJsonEntity.class) RebootType rebootType); /** * The resize function converts an existing server to a different flavor, in essence, scaling the @@ -192,7 +192,7 @@ public interface CloudServersConnection { // TODO:cloudServersFault (400, 500), serviceUnavailable (503), unauthorized (401), badRequest // (400), badMediaType(415), itemNotFound (404), buildInProgress (409), serverCapacityUnavailable // (503), overLimit (413), resizeNotAllowed (403) - boolean resizeServer(@PathParam("id") int id, @EntityParam(ResizeBinder.class) int flavorId); + boolean resizeServer(@PathParam("id") int id, @DecoratorParam(AddResizeFlavorAsJsonEntity.class) int flavorId); /** * The resize function converts an existing server to a different flavor, in essence, scaling the @@ -212,7 +212,7 @@ public interface CloudServersConnection { // TODO:cloudServersFault (400, 500), serviceUnavailable (503), unauthorized (401), badRequest // (400), badMediaType(415), itemNotFound (404), buildInProgress (409), serverCapacityUnavailable // (503), overLimit (413), resizeNotAllowed (403) - boolean confirmResizeServer(@PathParam("id") @EntityParam(ConfirmResizeBinder.class) int id); + boolean confirmResizeServer(@PathParam("id") @DecoratorParam(AddConfirmResizeAsJsonEntity.class) int id); /** * The resize function converts an existing server to a different flavor, in essence, scaling the @@ -232,7 +232,7 @@ public interface CloudServersConnection { // TODO:cloudServersFault (400, 500), serviceUnavailable (503), unauthorized (401), badRequest // (400), badMediaType(415), itemNotFound (404), buildInProgress (409), serverCapacityUnavailable // (503), overLimit (413), resizeNotAllowed (403) - boolean revertResizeServer(@PathParam("id") @EntityParam(RevertResizeBinder.class) int id); + boolean revertResizeServer(@PathParam("id") @DecoratorParam(AddRevertResizeAsJsonEntity.class) int id); /** * This operation asynchronously provisions a new server. The progress of this operation depends @@ -304,7 +304,7 @@ public interface CloudServersConnection { @PUT @ExceptionParser(ReturnFalseOn404.class) @Path("/servers/{id}/ips/public/{address}") - @MapBinder(ShareIpBinder.class) + @MapBinder(AddSharedIpGroupAsJsonEntity.class) // TODO: cloudServersFault (400, 500), serviceUnavailable (503), unauthorized (401), badRequest // (400), badMediaType(415), buildInProgress (409), overLimit (413) boolean shareIp(@PathParam("address") @ParamParser(IpAddress.class) InetAddress addressToShare, @@ -344,7 +344,7 @@ public interface CloudServersConnection { // TODO: cloudServersFault (400, 500), serviceUnavailable (503), unauthorized (401), badRequest // (400), badMediaType(415), buildInProgress (409), overLimit (413) boolean changeAdminPass(@PathParam("id") int id, - @EntityParam(ChangeAdminPassBinder.class) String adminPass); + @DecoratorParam(AddAdminPassAsJsonEntity.class) String adminPass); /** * This operation allows you to update the name of the server. This operation changes the name of @@ -360,7 +360,7 @@ public interface CloudServersConnection { // TODO: cloudServersFault (400, 500), serviceUnavailable (503), unauthorized (401), badRequest // (400), badMediaType(415), buildInProgress (409), overLimit (413) boolean renameServer(@PathParam("id") int id, - @EntityParam(ChangeServerNameBinder.class) String newName); + @DecoratorParam(AddServerNameAsJsonEntity.class) String newName); /** * @@ -447,7 +447,7 @@ public interface CloudServersConnection { @ResponseParser(ParseImageFromJsonResponse.class) @QueryParams(keys = "format", values = "json") @ExceptionParser(ReturnImageNotFoundOn404.class) - @MapBinder(CreateImageBinder.class) + @MapBinder(AddCreateImageAsJsonEntity.class) @Path("/images") // TODO: cloudServersFault (400, 500), serviceUnavailable (503), unauthorized (401), badRequest // (400), badMediaType(415), buildInProgress (409), serverCapacityUnavailable (503), overLimit @@ -554,7 +554,7 @@ public interface CloudServersConnection { // (400), badMediaType(415), buildInProgress (409), serverCapacityUnavailable (503), // backupOrResizeInProgress(409), resizeNotAllowed (403). overLimit (413) boolean replaceBackupSchedule(@PathParam("id") int id, - @EntityParam(BackupScheduleBinder.class) BackupSchedule backupSchedule); + @DecoratorParam(AddBackupScheduleAsJsonEntity.class) BackupSchedule backupSchedule); /** * List all server addresses diff --git a/rackspace/cloudservers/core/src/main/java/org/jclouds/rackspace/cloudservers/binders/ChangeAdminPassBinder.java b/rackspace/cloudservers/core/src/main/java/org/jclouds/rackspace/cloudservers/decorators/AddAdminPassAsJsonEntity.java similarity index 75% rename from rackspace/cloudservers/core/src/main/java/org/jclouds/rackspace/cloudservers/binders/ChangeAdminPassBinder.java rename to rackspace/cloudservers/core/src/main/java/org/jclouds/rackspace/cloudservers/decorators/AddAdminPassAsJsonEntity.java index eafca3c7ff..1fda2d06c1 100644 --- a/rackspace/cloudservers/core/src/main/java/org/jclouds/rackspace/cloudservers/binders/ChangeAdminPassBinder.java +++ b/rackspace/cloudservers/core/src/main/java/org/jclouds/rackspace/cloudservers/decorators/AddAdminPassAsJsonEntity.java @@ -21,7 +21,7 @@ * under the License. * ==================================================================== */ -package org.jclouds.rackspace.cloudservers.binders; +package org.jclouds.rackspace.cloudservers.decorators; import static com.google.common.base.Preconditions.checkArgument; import static com.google.common.base.Preconditions.checkNotNull; @@ -29,7 +29,7 @@ import static com.google.common.base.Preconditions.checkNotNull; import java.util.Map; import org.jclouds.http.HttpRequest; -import org.jclouds.rest.binders.JsonBinder; +import org.jclouds.rest.decorators.AddAsJsonEntity; import com.google.common.collect.ImmutableMap; @@ -38,17 +38,17 @@ import com.google.common.collect.ImmutableMap; * @author Adrian Cole * */ -public class ChangeAdminPassBinder extends JsonBinder { +public class AddAdminPassAsJsonEntity extends AddAsJsonEntity { @Override - public void addEntityToRequest(Map postParams, HttpRequest request) { + public HttpRequest decorateRequest(HttpRequest request, Map postParams) { throw new IllegalStateException("Change Admin Pass is a PUT operation"); } @Override - public void addEntityToRequest(Object toBind, HttpRequest request) { + public HttpRequest decorateRequest(HttpRequest request, Object toBind) { checkArgument(toBind instanceof String, "this binder is only valid for Strings!"); - super.addEntityToRequest(ImmutableMap.of("server", ImmutableMap.of("adminPass", checkNotNull( - toBind, "adminPass"))), request); + return super.decorateRequest(request, ImmutableMap.of("server", ImmutableMap.of("adminPass", + checkNotNull(toBind, "adminPass")))); } } diff --git a/rackspace/cloudservers/core/src/main/java/org/jclouds/rackspace/cloudservers/binders/BackupScheduleBinder.java b/rackspace/cloudservers/core/src/main/java/org/jclouds/rackspace/cloudservers/decorators/AddBackupScheduleAsJsonEntity.java similarity index 78% rename from rackspace/cloudservers/core/src/main/java/org/jclouds/rackspace/cloudservers/binders/BackupScheduleBinder.java rename to rackspace/cloudservers/core/src/main/java/org/jclouds/rackspace/cloudservers/decorators/AddBackupScheduleAsJsonEntity.java index 31b8253ee8..a46504a633 100644 --- a/rackspace/cloudservers/core/src/main/java/org/jclouds/rackspace/cloudservers/binders/BackupScheduleBinder.java +++ b/rackspace/cloudservers/core/src/main/java/org/jclouds/rackspace/cloudservers/decorators/AddBackupScheduleAsJsonEntity.java @@ -21,15 +21,15 @@ * under the License. * ==================================================================== */ -package org.jclouds.rackspace.cloudservers.binders; +package org.jclouds.rackspace.cloudservers.decorators; import static com.google.common.base.Preconditions.checkArgument; import java.util.Map; import org.jclouds.http.HttpRequest; -import org.jclouds.rest.binders.JsonBinder; import org.jclouds.rackspace.cloudservers.domain.BackupSchedule; +import org.jclouds.rest.decorators.AddAsJsonEntity; import com.google.common.collect.ImmutableMap; @@ -38,18 +38,18 @@ import com.google.common.collect.ImmutableMap; * @author Adrian Cole * */ -public class BackupScheduleBinder extends JsonBinder { +public class AddBackupScheduleAsJsonEntity extends AddAsJsonEntity { @Override - public void addEntityToRequest(Map postParams, HttpRequest request) { + public HttpRequest decorateRequest(HttpRequest request, Map postParams) { throw new IllegalStateException( "Replace Backup Schedule needs an BackupSchedule object, not a Map"); } @Override - public void addEntityToRequest(Object toBind, HttpRequest request) { + public HttpRequest decorateRequest(HttpRequest request, Object toBind) { checkArgument(toBind instanceof BackupSchedule, "this binder is only valid for BackupSchedules!"); - super.addEntityToRequest(ImmutableMap.of("backupSchedule", toBind), request); + return super.decorateRequest(request, ImmutableMap.of("backupSchedule", toBind)); } } diff --git a/rackspace/cloudservers/core/src/main/java/org/jclouds/rackspace/cloudservers/binders/ConfirmResizeBinder.java b/rackspace/cloudservers/core/src/main/java/org/jclouds/rackspace/cloudservers/decorators/AddConfirmResizeAsJsonEntity.java similarity index 85% rename from rackspace/cloudservers/core/src/main/java/org/jclouds/rackspace/cloudservers/binders/ConfirmResizeBinder.java rename to rackspace/cloudservers/core/src/main/java/org/jclouds/rackspace/cloudservers/decorators/AddConfirmResizeAsJsonEntity.java index 1621fb179c..96482cd693 100644 --- a/rackspace/cloudservers/core/src/main/java/org/jclouds/rackspace/cloudservers/binders/ConfirmResizeBinder.java +++ b/rackspace/cloudservers/core/src/main/java/org/jclouds/rackspace/cloudservers/decorators/AddConfirmResizeAsJsonEntity.java @@ -21,7 +21,7 @@ * under the License. * ==================================================================== */ -package org.jclouds.rackspace.cloudservers.binders; +package org.jclouds.rackspace.cloudservers.decorators; import java.util.Collections; @@ -29,20 +29,21 @@ import javax.ws.rs.core.HttpHeaders; import javax.ws.rs.core.MediaType; import org.jclouds.http.HttpRequest; -import org.jclouds.rest.binders.EntityBinder; +import org.jclouds.rest.decorators.RequestDecorator; /** * * @author Adrian Cole * */ -public class ConfirmResizeBinder implements EntityBinder { +public class AddConfirmResizeAsJsonEntity implements RequestDecorator { - public void addEntityToRequest(Object toBind, HttpRequest request) { + public HttpRequest decorateRequest(HttpRequest request, Object toBind) { request.setEntity("{\"confirmResize\":null}"); request.getHeaders().replaceValues(HttpHeaders.CONTENT_LENGTH, Collections.singletonList("{\"confirmResize\":null}".getBytes().length + "")); request.getHeaders().replaceValues(HttpHeaders.CONTENT_TYPE, Collections.singletonList(MediaType.APPLICATION_JSON)); + return request; } } diff --git a/rackspace/cloudservers/core/src/main/java/org/jclouds/rackspace/cloudservers/binders/CreateImageBinder.java b/rackspace/cloudservers/core/src/main/java/org/jclouds/rackspace/cloudservers/decorators/AddCreateImageAsJsonEntity.java similarity index 81% rename from rackspace/cloudservers/core/src/main/java/org/jclouds/rackspace/cloudservers/binders/CreateImageBinder.java rename to rackspace/cloudservers/core/src/main/java/org/jclouds/rackspace/cloudservers/decorators/AddCreateImageAsJsonEntity.java index ea14794bf6..dcc28c1ae7 100644 --- a/rackspace/cloudservers/core/src/main/java/org/jclouds/rackspace/cloudservers/binders/CreateImageBinder.java +++ b/rackspace/cloudservers/core/src/main/java/org/jclouds/rackspace/cloudservers/decorators/AddCreateImageAsJsonEntity.java @@ -21,14 +21,14 @@ * under the License. * ==================================================================== */ -package org.jclouds.rackspace.cloudservers.binders; +package org.jclouds.rackspace.cloudservers.decorators; import static com.google.common.base.Preconditions.checkNotNull; import java.util.Map; import org.jclouds.http.HttpRequest; -import org.jclouds.rest.binders.JsonBinder; +import org.jclouds.rest.decorators.AddAsJsonEntity; import com.google.common.collect.ImmutableMap; @@ -37,7 +37,7 @@ import com.google.common.collect.ImmutableMap; * @author Adrian Cole * */ -public class CreateImageBinder extends JsonBinder { +public class AddCreateImageAsJsonEntity extends AddAsJsonEntity { @SuppressWarnings("unused") private class CreateImageRequest { @@ -52,15 +52,15 @@ public class CreateImageBinder extends JsonBinder { } @Override - public void addEntityToRequest(Map postParams, HttpRequest request) { + public HttpRequest decorateRequest(HttpRequest request, Map postParams) { CreateImageRequest createRequest = new CreateImageRequest(Integer .parseInt(checkNotNull(postParams.get("serverId"))), checkNotNull(postParams .get("imageName"))); - super.addEntityToRequest(ImmutableMap.of("image", createRequest), request); + return super.decorateRequest(request, ImmutableMap.of("image", createRequest)); } @Override - public void addEntityToRequest(Object toBind, HttpRequest request) { + public HttpRequest decorateRequest(HttpRequest request, Object toBind) { throw new IllegalArgumentException("image is needs parameters"); } } diff --git a/rackspace/cloudservers/core/src/main/java/org/jclouds/rackspace/cloudservers/binders/RebootTypeBinder.java b/rackspace/cloudservers/core/src/main/java/org/jclouds/rackspace/cloudservers/decorators/AddRebootTypeAsJsonEntity.java similarity index 76% rename from rackspace/cloudservers/core/src/main/java/org/jclouds/rackspace/cloudservers/binders/RebootTypeBinder.java rename to rackspace/cloudservers/core/src/main/java/org/jclouds/rackspace/cloudservers/decorators/AddRebootTypeAsJsonEntity.java index 0ab78c96d8..ba90e4f7ed 100644 --- a/rackspace/cloudservers/core/src/main/java/org/jclouds/rackspace/cloudservers/binders/RebootTypeBinder.java +++ b/rackspace/cloudservers/core/src/main/java/org/jclouds/rackspace/cloudservers/decorators/AddRebootTypeAsJsonEntity.java @@ -21,7 +21,7 @@ * under the License. * ==================================================================== */ -package org.jclouds.rackspace.cloudservers.binders; +package org.jclouds.rackspace.cloudservers.decorators; import static com.google.common.base.Preconditions.checkArgument; import static com.google.common.base.Preconditions.checkNotNull; @@ -29,8 +29,8 @@ import static com.google.common.base.Preconditions.checkNotNull; import java.util.Map; import org.jclouds.http.HttpRequest; -import org.jclouds.rest.binders.JsonBinder; import org.jclouds.rackspace.cloudservers.domain.RebootType; +import org.jclouds.rest.decorators.AddAsJsonEntity; import com.google.common.collect.ImmutableMap; @@ -39,17 +39,17 @@ import com.google.common.collect.ImmutableMap; * @author Adrian Cole * */ -public class RebootTypeBinder extends JsonBinder { +public class AddRebootTypeAsJsonEntity extends AddAsJsonEntity { @Override - public void addEntityToRequest(Map postParams, HttpRequest request) { + public HttpRequest decorateRequest(HttpRequest request, Map postParams) { throw new IllegalStateException("Reboot doesn't take map parameters"); } @Override - public void addEntityToRequest(Object toBind, HttpRequest request) { + public HttpRequest decorateRequest(HttpRequest request, Object toBind) { checkArgument(toBind instanceof RebootType, "this binder is only valid for RebootTypes!"); - super.addEntityToRequest(ImmutableMap.of("reboot", ImmutableMap.of("type", checkNotNull( - toBind, "type"))), request); + return super.decorateRequest(request, ImmutableMap.of("reboot", ImmutableMap.of("type", + checkNotNull(toBind, "type")))); } } diff --git a/rackspace/cloudservers/core/src/main/java/org/jclouds/rackspace/cloudservers/binders/ResizeBinder.java b/rackspace/cloudservers/core/src/main/java/org/jclouds/rackspace/cloudservers/decorators/AddResizeFlavorAsJsonEntity.java similarity index 75% rename from rackspace/cloudservers/core/src/main/java/org/jclouds/rackspace/cloudservers/binders/ResizeBinder.java rename to rackspace/cloudservers/core/src/main/java/org/jclouds/rackspace/cloudservers/decorators/AddResizeFlavorAsJsonEntity.java index 050e079a62..e48d057463 100644 --- a/rackspace/cloudservers/core/src/main/java/org/jclouds/rackspace/cloudservers/binders/ResizeBinder.java +++ b/rackspace/cloudservers/core/src/main/java/org/jclouds/rackspace/cloudservers/decorators/AddResizeFlavorAsJsonEntity.java @@ -21,7 +21,7 @@ * under the License. * ==================================================================== */ -package org.jclouds.rackspace.cloudservers.binders; +package org.jclouds.rackspace.cloudservers.decorators; import static com.google.common.base.Preconditions.checkArgument; import static com.google.common.base.Preconditions.checkNotNull; @@ -29,7 +29,7 @@ import static com.google.common.base.Preconditions.checkNotNull; import java.util.Map; import org.jclouds.http.HttpRequest; -import org.jclouds.rest.binders.JsonBinder; +import org.jclouds.rest.decorators.AddAsJsonEntity; import com.google.common.collect.ImmutableMap; @@ -38,17 +38,17 @@ import com.google.common.collect.ImmutableMap; * @author Adrian Cole * */ -public class ResizeBinder extends JsonBinder { +public class AddResizeFlavorAsJsonEntity extends AddAsJsonEntity { @Override - public void addEntityToRequest(Map postParams, HttpRequest request) { + public HttpRequest decorateRequest(HttpRequest request, Map postParams) { throw new IllegalStateException("Resize doesn't take map parameters"); } @Override - public void addEntityToRequest(Object toBind, HttpRequest request) { + public HttpRequest decorateRequest(HttpRequest request, Object toBind) { checkArgument(toBind instanceof Integer, "this binder is only valid for integers!"); - super.addEntityToRequest(ImmutableMap.of("resize", ImmutableMap.of("flavorId", - (Integer) checkNotNull(toBind, "flavorId"))), request); + return super.decorateRequest(request, ImmutableMap.of("resize", ImmutableMap.of("flavorId", + (Integer) checkNotNull(toBind, "flavorId")))); } } diff --git a/rackspace/cloudservers/core/src/main/java/org/jclouds/rackspace/cloudservers/binders/RevertResizeBinder.java b/rackspace/cloudservers/core/src/main/java/org/jclouds/rackspace/cloudservers/decorators/AddRevertResizeAsJsonEntity.java similarity index 85% rename from rackspace/cloudservers/core/src/main/java/org/jclouds/rackspace/cloudservers/binders/RevertResizeBinder.java rename to rackspace/cloudservers/core/src/main/java/org/jclouds/rackspace/cloudservers/decorators/AddRevertResizeAsJsonEntity.java index e1bcbedebb..9c51bab8c9 100644 --- a/rackspace/cloudservers/core/src/main/java/org/jclouds/rackspace/cloudservers/binders/RevertResizeBinder.java +++ b/rackspace/cloudservers/core/src/main/java/org/jclouds/rackspace/cloudservers/decorators/AddRevertResizeAsJsonEntity.java @@ -21,7 +21,7 @@ * under the License. * ==================================================================== */ -package org.jclouds.rackspace.cloudservers.binders; +package org.jclouds.rackspace.cloudservers.decorators; import java.util.Collections; @@ -29,20 +29,21 @@ import javax.ws.rs.core.HttpHeaders; import javax.ws.rs.core.MediaType; import org.jclouds.http.HttpRequest; -import org.jclouds.rest.binders.EntityBinder; +import org.jclouds.rest.decorators.RequestDecorator; /** * * @author Adrian Cole * */ -public class RevertResizeBinder implements EntityBinder { +public class AddRevertResizeAsJsonEntity implements RequestDecorator { - public void addEntityToRequest(Object toBind, HttpRequest request) { + public HttpRequest decorateRequest(HttpRequest request, Object toBind) { request.setEntity("{\"revertResize\":null}"); request.getHeaders().replaceValues(HttpHeaders.CONTENT_LENGTH, Collections.singletonList("{\"revertResize\":null}".getBytes().length + "")); request.getHeaders().replaceValues(HttpHeaders.CONTENT_TYPE, Collections.singletonList(MediaType.APPLICATION_JSON)); + return request; } } diff --git a/rackspace/cloudservers/core/src/main/java/org/jclouds/rackspace/cloudservers/binders/ChangeServerNameBinder.java b/rackspace/cloudservers/core/src/main/java/org/jclouds/rackspace/cloudservers/decorators/AddServerNameAsJsonEntity.java similarity index 76% rename from rackspace/cloudservers/core/src/main/java/org/jclouds/rackspace/cloudservers/binders/ChangeServerNameBinder.java rename to rackspace/cloudservers/core/src/main/java/org/jclouds/rackspace/cloudservers/decorators/AddServerNameAsJsonEntity.java index e19d85a2f0..05c64a470c 100644 --- a/rackspace/cloudservers/core/src/main/java/org/jclouds/rackspace/cloudservers/binders/ChangeServerNameBinder.java +++ b/rackspace/cloudservers/core/src/main/java/org/jclouds/rackspace/cloudservers/decorators/AddServerNameAsJsonEntity.java @@ -21,7 +21,7 @@ * under the License. * ==================================================================== */ -package org.jclouds.rackspace.cloudservers.binders; +package org.jclouds.rackspace.cloudservers.decorators; import static com.google.common.base.Preconditions.checkArgument; import static com.google.common.base.Preconditions.checkNotNull; @@ -29,7 +29,7 @@ import static com.google.common.base.Preconditions.checkNotNull; import java.util.Map; import org.jclouds.http.HttpRequest; -import org.jclouds.rest.binders.JsonBinder; +import org.jclouds.rest.decorators.AddAsJsonEntity; import com.google.common.collect.ImmutableMap; @@ -38,17 +38,17 @@ import com.google.common.collect.ImmutableMap; * @author Adrian Cole * */ -public class ChangeServerNameBinder extends JsonBinder { +public class AddServerNameAsJsonEntity extends AddAsJsonEntity { @Override - public void addEntityToRequest(Map postParams, HttpRequest request) { + public HttpRequest decorateRequest(HttpRequest request, Map postParams) { throw new IllegalStateException("Change Server Name is a PUT operation"); } @Override - public void addEntityToRequest(Object toBind, HttpRequest request) { + public HttpRequest decorateRequest(HttpRequest request, Object toBind) { checkArgument(toBind instanceof String, "this binder is only valid for Strings!"); - super.addEntityToRequest(ImmutableMap.of("server", ImmutableMap.of("name", checkNotNull( - toBind, "name"))), request); + return super.decorateRequest(request, ImmutableMap.of("server", ImmutableMap.of("name", + checkNotNull(toBind, "name")))); } } diff --git a/rackspace/cloudservers/core/src/main/java/org/jclouds/rackspace/cloudservers/binders/ShareIpBinder.java b/rackspace/cloudservers/core/src/main/java/org/jclouds/rackspace/cloudservers/decorators/AddSharedIpGroupAsJsonEntity.java similarity index 81% rename from rackspace/cloudservers/core/src/main/java/org/jclouds/rackspace/cloudservers/binders/ShareIpBinder.java rename to rackspace/cloudservers/core/src/main/java/org/jclouds/rackspace/cloudservers/decorators/AddSharedIpGroupAsJsonEntity.java index df6607f552..65cbe989b3 100644 --- a/rackspace/cloudservers/core/src/main/java/org/jclouds/rackspace/cloudservers/binders/ShareIpBinder.java +++ b/rackspace/cloudservers/core/src/main/java/org/jclouds/rackspace/cloudservers/decorators/AddSharedIpGroupAsJsonEntity.java @@ -21,14 +21,14 @@ * under the License. * ==================================================================== */ -package org.jclouds.rackspace.cloudservers.binders; +package org.jclouds.rackspace.cloudservers.decorators; import static com.google.common.base.Preconditions.checkNotNull; import java.util.Map; import org.jclouds.http.HttpRequest; -import org.jclouds.rest.binders.JsonBinder; +import org.jclouds.rest.decorators.AddAsJsonEntity; import com.google.common.collect.ImmutableMap; @@ -37,7 +37,7 @@ import com.google.common.collect.ImmutableMap; * @author Adrian Cole * */ -public class ShareIpBinder extends JsonBinder { +public class AddSharedIpGroupAsJsonEntity extends AddAsJsonEntity { @SuppressWarnings("unused") private class ShareIpRequest { @@ -51,17 +51,17 @@ public class ShareIpBinder extends JsonBinder { } @Override - public void addEntityToRequest(Map postParams, HttpRequest request) { + public HttpRequest decorateRequest(HttpRequest request, Map postParams) { ShareIpRequest createRequest = new ShareIpRequest(Integer.parseInt(checkNotNull(postParams .get("sharedIpGroupId")))); if (Boolean.parseBoolean(checkNotNull(postParams.get("configureServer")))) { createRequest.configureServer = new Boolean(true); } - super.addEntityToRequest(ImmutableMap.of("shareIp", createRequest), request); + return super.decorateRequest(request, ImmutableMap.of("shareIp", createRequest)); } @Override - public void addEntityToRequest(Object toBind, HttpRequest request) { + public HttpRequest decorateRequest(HttpRequest request, Object toBind) { throw new IllegalStateException("shareIp is needs parameters"); } } diff --git a/rackspace/cloudservers/core/src/main/java/org/jclouds/rackspace/cloudservers/options/CreateServerOptions.java b/rackspace/cloudservers/core/src/main/java/org/jclouds/rackspace/cloudservers/options/CreateServerOptions.java index ec53d62b09..d5ab564ad1 100644 --- a/rackspace/cloudservers/core/src/main/java/org/jclouds/rackspace/cloudservers/options/CreateServerOptions.java +++ b/rackspace/cloudservers/core/src/main/java/org/jclouds/rackspace/cloudservers/options/CreateServerOptions.java @@ -35,8 +35,8 @@ import java.util.Map.Entry; import org.jclouds.http.HttpRequest; import org.jclouds.http.HttpUtils; -import org.jclouds.rest.binders.JsonBinder; import org.jclouds.rackspace.cloudservers.domain.Addresses; +import org.jclouds.rest.decorators.AddAsJsonEntity; import com.google.common.collect.ImmutableMap; import com.google.inject.internal.Lists; @@ -47,7 +47,7 @@ import com.google.inject.internal.Maps; * @author Adrian Cole * */ -public class CreateServerOptions extends JsonBinder { +public class CreateServerOptions extends AddAsJsonEntity { static class File { private final String path; @@ -98,7 +98,7 @@ public class CreateServerOptions extends JsonBinder { private InetAddress publicIp; @Override - public void addEntityToRequest(Map postParams, HttpRequest request) { + public HttpRequest decorateRequest(HttpRequest request, Map postParams) { ServerRequest server = new ServerRequest(checkNotNull(postParams.get("name"), "name parameter not present"), Integer.parseInt(checkNotNull(postParams @@ -115,7 +115,7 @@ public class CreateServerOptions extends JsonBinder { server.addresses.setPublicAddresses(Collections.singletonList(publicIp)); server.addresses.setPrivateAddresses(null); } - addEntityToRequest(ImmutableMap.of("server", server), request); + return decorateRequest(request, ImmutableMap.of("server", server)); } /** diff --git a/rackspace/cloudservers/core/src/main/java/org/jclouds/rackspace/cloudservers/options/CreateSharedIpGroupOptions.java b/rackspace/cloudservers/core/src/main/java/org/jclouds/rackspace/cloudservers/options/CreateSharedIpGroupOptions.java index 9483f57f98..b02520081e 100644 --- a/rackspace/cloudservers/core/src/main/java/org/jclouds/rackspace/cloudservers/options/CreateSharedIpGroupOptions.java +++ b/rackspace/cloudservers/core/src/main/java/org/jclouds/rackspace/cloudservers/options/CreateSharedIpGroupOptions.java @@ -29,7 +29,7 @@ import static com.google.common.base.Preconditions.checkNotNull; import java.util.Map; import org.jclouds.http.HttpRequest; -import org.jclouds.rest.binders.JsonBinder; +import org.jclouds.rest.decorators.AddAsJsonEntity; import com.google.common.collect.ImmutableMap; import com.google.inject.internal.Nullable; @@ -40,7 +40,7 @@ import com.google.inject.internal.Nullable; * @author Adrian Cole * */ -public class CreateSharedIpGroupOptions extends JsonBinder { +public class CreateSharedIpGroupOptions extends AddAsJsonEntity { Integer serverId; @SuppressWarnings("unused") @@ -56,14 +56,14 @@ public class CreateSharedIpGroupOptions extends JsonBinder { } @Override - public void addEntityToRequest(Map postParams, HttpRequest request) { + public HttpRequest decorateRequest(HttpRequest request, Map postParams) { SharedIpGroupRequest createRequest = new SharedIpGroupRequest(checkNotNull(postParams .get("name")), serverId); - super.addEntityToRequest(ImmutableMap.of("sharedIpGroup", createRequest), request); + return super.decorateRequest(request, ImmutableMap.of("sharedIpGroup", createRequest)); } @Override - public void addEntityToRequest(Object toBind, HttpRequest request) { + public HttpRequest decorateRequest(HttpRequest request, Object toBind) { throw new IllegalStateException("CreateSharedIpGroup is a POST operation"); } diff --git a/rackspace/cloudservers/core/src/main/java/org/jclouds/rackspace/cloudservers/options/RebuildServerOptions.java b/rackspace/cloudservers/core/src/main/java/org/jclouds/rackspace/cloudservers/options/RebuildServerOptions.java index bdd83c6891..bd1dbbec49 100644 --- a/rackspace/cloudservers/core/src/main/java/org/jclouds/rackspace/cloudservers/options/RebuildServerOptions.java +++ b/rackspace/cloudservers/core/src/main/java/org/jclouds/rackspace/cloudservers/options/RebuildServerOptions.java @@ -28,7 +28,7 @@ import static com.google.common.base.Preconditions.checkArgument; import java.util.Map; import org.jclouds.http.HttpRequest; -import org.jclouds.rest.binders.JsonBinder; +import org.jclouds.rest.decorators.AddAsJsonEntity; import com.google.common.collect.ImmutableMap; import com.google.inject.internal.Maps; @@ -39,19 +39,19 @@ import com.google.inject.internal.Maps; * @author Adrian Cole * */ -public class RebuildServerOptions extends JsonBinder { +public class RebuildServerOptions extends AddAsJsonEntity { Integer imageId; @Override - public void addEntityToRequest(Map postParams, HttpRequest request) { + public HttpRequest decorateRequest(HttpRequest request, Map postParams) { Map image = Maps.newHashMap(); if (imageId != null) image.put("imageId", imageId); - super.addEntityToRequest(ImmutableMap.of("rebuild", image), request); + return super.decorateRequest(request, ImmutableMap.of("rebuild", image)); } @Override - public void addEntityToRequest(Object toBind, HttpRequest request) { + public HttpRequest decorateRequest(HttpRequest request, Object toBind) { throw new IllegalStateException("RebuildServer is a POST operation"); } diff --git a/rackspace/cloudservers/core/src/test/java/org/jclouds/rackspace/cloudservers/CloudServersConnectionTest.java b/rackspace/cloudservers/core/src/test/java/org/jclouds/rackspace/cloudservers/CloudServersConnectionTest.java index 13050ec82b..5ae5ecc209 100755 --- a/rackspace/cloudservers/core/src/test/java/org/jclouds/rackspace/cloudservers/CloudServersConnectionTest.java +++ b/rackspace/cloudservers/core/src/test/java/org/jclouds/rackspace/cloudservers/CloudServersConnectionTest.java @@ -74,8 +74,8 @@ import org.jclouds.rackspace.cloudservers.options.CreateServerOptions; import org.jclouds.rackspace.cloudservers.options.CreateSharedIpGroupOptions; import org.jclouds.rackspace.cloudservers.options.ListOptions; import org.jclouds.rackspace.cloudservers.options.RebuildServerOptions; -import org.jclouds.rest.JaxrsAnnotationProcessor; -import org.jclouds.rest.config.JaxrsModule; +import org.jclouds.rest.config.RestModule; +import org.jclouds.rest.internal.RestAnnotationProcessor; import org.joda.time.DateTime; import org.testng.annotations.BeforeClass; import org.testng.annotations.Test; @@ -489,8 +489,8 @@ public class CloudServersConnectionTest { assertEquals(httpMethod.getHeaders().get(HttpHeaders.CONTENT_TYPE), Collections .singletonList(MediaType.APPLICATION_JSON)); assertEquals( - "{\"backupSchedule\":{\"daily\":\"H_0800_1000\",\"enabled\":true,\"weekly\":\"MONDAY\"}}", - httpMethod.getEntity()); + httpMethod.getEntity(), + "{\"backupSchedule\":{\"daily\":\"H_0800_1000\",\"enabled\":true,\"weekly\":\"MONDAY\"}}"); assertEquals(processor.createExceptionParserOrNullIfNotFound(method).getClass(), ReturnFalseOn404.class); assertEquals(processor.createResponseParser(method, httpMethod, null).getClass(), @@ -888,13 +888,13 @@ public class CloudServersConnectionTest { public String getAuthToken() { return "testtoken"; } - }, new JaxrsModule(), new ExecutorServiceModule(new WithinThreadExecutorService()), + }, new RestModule(), new ExecutorServiceModule(new WithinThreadExecutorService()), new JavaUrlHttpCommandExecutorServiceModule()); processor = injector.getInstance(Key - .get(new TypeLiteral>() { + .get(new TypeLiteral>() { })); } - JaxrsAnnotationProcessor processor; + RestAnnotationProcessor processor; } diff --git a/rackspace/cloudservers/core/src/test/java/org/jclouds/rackspace/cloudservers/binders/ChangeAdminPassBinderTest.java b/rackspace/cloudservers/core/src/test/java/org/jclouds/rackspace/cloudservers/decorators/AddAdminPassAsJsonEntityTest.java similarity index 77% rename from rackspace/cloudservers/core/src/test/java/org/jclouds/rackspace/cloudservers/binders/ChangeAdminPassBinderTest.java rename to rackspace/cloudservers/core/src/test/java/org/jclouds/rackspace/cloudservers/decorators/AddAdminPassAsJsonEntityTest.java index 3011103ad5..3e8049de4c 100644 --- a/rackspace/cloudservers/core/src/test/java/org/jclouds/rackspace/cloudservers/binders/ChangeAdminPassBinderTest.java +++ b/rackspace/cloudservers/core/src/test/java/org/jclouds/rackspace/cloudservers/decorators/AddAdminPassAsJsonEntityTest.java @@ -21,7 +21,7 @@ * under the License. * ==================================================================== */ -package org.jclouds.rackspace.cloudservers.binders; +package org.jclouds.rackspace.cloudservers.decorators; import static org.testng.Assert.assertEquals; @@ -39,45 +39,45 @@ import com.google.inject.Guice; import com.google.inject.Injector; /** - * Tests behavior of {@code ChangeAdminPassBinder} + * Tests behavior of {@code AddAdminPassAsJsonEntity} * * @author Adrian Cole */ -@Test(groups = "unit", testName = "cloudservers.ChangeAdminPassBinderTest") -public class ChangeAdminPassBinderTest { +@Test(groups = "unit", testName = "cloudservers.AddAdminPassAsJsonEntityTest") +public class AddAdminPassAsJsonEntityTest { Injector injector = Guice.createInjector(new ParserModule()); @Test(expectedExceptions = IllegalStateException.class) public void testPostIsIncorrect() { - ChangeAdminPassBinder binder = new ChangeAdminPassBinder(); + AddAdminPassAsJsonEntity binder = new AddAdminPassAsJsonEntity(); injector.injectMembers(binder); HttpRequest request = new HttpRequest(HttpMethod.POST, URI.create("http://localhost")); - binder.addEntityToRequest(ImmutableMap.of("adminPass", "foo"), request); + binder.decorateRequest(request, ImmutableMap.of("adminPass", "foo")); } @Test(expectedExceptions = IllegalArgumentException.class) public void testMustBeString() { - ChangeAdminPassBinder binder = new ChangeAdminPassBinder(); + AddAdminPassAsJsonEntity binder = new AddAdminPassAsJsonEntity(); injector.injectMembers(binder); HttpRequest request = new HttpRequest(HttpMethod.POST, URI.create("http://localhost")); - binder.addEntityToRequest(new File("foo"), request); + binder.decorateRequest(request, new File("foo")); } @Test public void testCorrect() { - ChangeAdminPassBinder binder = new ChangeAdminPassBinder(); + AddAdminPassAsJsonEntity binder = new AddAdminPassAsJsonEntity(); injector.injectMembers(binder); HttpRequest request = new HttpRequest(HttpMethod.PUT, URI.create("http://localhost")); - binder.addEntityToRequest("foo", request); + binder.decorateRequest(request, "foo"); assertEquals("{\"server\":{\"adminPass\":\"foo\"}}", request.getEntity()); } @Test(expectedExceptions = { NullPointerException.class, IllegalStateException.class }) public void testNullIsBad() { - ChangeAdminPassBinder binder = new ChangeAdminPassBinder(); + AddAdminPassAsJsonEntity binder = new AddAdminPassAsJsonEntity(); injector.injectMembers(binder); HttpRequest request = new HttpRequest(HttpMethod.PUT, URI.create("http://localhost")); - binder.addEntityToRequest(null, request); + binder.decorateRequest(request, null); } } diff --git a/rackspace/cloudservers/core/src/test/java/org/jclouds/rackspace/cloudservers/binders/CreateImageBinderTest.java b/rackspace/cloudservers/core/src/test/java/org/jclouds/rackspace/cloudservers/decorators/AddCreateImageAsJsonEntityTest.java similarity index 77% rename from rackspace/cloudservers/core/src/test/java/org/jclouds/rackspace/cloudservers/binders/CreateImageBinderTest.java rename to rackspace/cloudservers/core/src/test/java/org/jclouds/rackspace/cloudservers/decorators/AddCreateImageAsJsonEntityTest.java index 8f391f336f..eae1a0a0c0 100644 --- a/rackspace/cloudservers/core/src/test/java/org/jclouds/rackspace/cloudservers/binders/CreateImageBinderTest.java +++ b/rackspace/cloudservers/core/src/test/java/org/jclouds/rackspace/cloudservers/decorators/AddCreateImageAsJsonEntityTest.java @@ -21,7 +21,7 @@ * under the License. * ==================================================================== */ -package org.jclouds.rackspace.cloudservers.binders; +package org.jclouds.rackspace.cloudservers.decorators; import static org.testng.Assert.assertEquals; @@ -39,37 +39,37 @@ import com.google.inject.Guice; import com.google.inject.Injector; /** - * Tests behavior of {@code CreateImageBinder} + * Tests behavior of {@code AddCreateImageAsJsonEntity} * * @author Adrian Cole */ -@Test(groups = "unit", testName = "cloudservers.CreateImageBinderTest") -public class CreateImageBinderTest { +@Test(groups = "unit", testName = "cloudservers.AddCreateImageAsJsonEntityTest") +public class AddCreateImageAsJsonEntityTest { Injector injector = Guice.createInjector(new ParserModule()); @Test(expectedExceptions = IllegalArgumentException.class) public void testMustBeMap() { - CreateImageBinder binder = new CreateImageBinder(); + AddCreateImageAsJsonEntity binder = new AddCreateImageAsJsonEntity(); injector.injectMembers(binder); HttpRequest request = new HttpRequest(HttpMethod.POST, URI.create("http://localhost")); - binder.addEntityToRequest(new File("foo"), request); + binder.decorateRequest(request, new File("foo")); } @Test public void testCorrect() { - CreateImageBinder binder = new CreateImageBinder(); + AddCreateImageAsJsonEntity binder = new AddCreateImageAsJsonEntity(); injector.injectMembers(binder); HttpRequest request = new HttpRequest(HttpMethod.PUT, URI.create("http://localhost")); - binder.addEntityToRequest(ImmutableMap.of("imageName", "foo", "serverId", "2"), request); + binder.decorateRequest(request, ImmutableMap.of("imageName", "foo", "serverId", "2")); assertEquals("{\"image\":{\"serverId\":2,\"name\":\"foo\"}}", request.getEntity()); } @Test(expectedExceptions = { NullPointerException.class, IllegalStateException.class }) public void testNullIsBad() { - CreateImageBinder binder = new CreateImageBinder(); + AddCreateImageAsJsonEntity binder = new AddCreateImageAsJsonEntity(); injector.injectMembers(binder); HttpRequest request = new HttpRequest(HttpMethod.PUT, URI.create("http://localhost")); - binder.addEntityToRequest(null, request); + binder.decorateRequest(request, null); } } diff --git a/rackspace/cloudservers/core/src/test/java/org/jclouds/rackspace/cloudservers/binders/RebootTypeBinderTest.java b/rackspace/cloudservers/core/src/test/java/org/jclouds/rackspace/cloudservers/decorators/AddRebootTypeAsJsonEntityTest.java similarity index 75% rename from rackspace/cloudservers/core/src/test/java/org/jclouds/rackspace/cloudservers/binders/RebootTypeBinderTest.java rename to rackspace/cloudservers/core/src/test/java/org/jclouds/rackspace/cloudservers/decorators/AddRebootTypeAsJsonEntityTest.java index aa5793a3aa..95c1bbf9ad 100644 --- a/rackspace/cloudservers/core/src/test/java/org/jclouds/rackspace/cloudservers/binders/RebootTypeBinderTest.java +++ b/rackspace/cloudservers/core/src/test/java/org/jclouds/rackspace/cloudservers/decorators/AddRebootTypeAsJsonEntityTest.java @@ -21,7 +21,7 @@ * under the License. * ==================================================================== */ -package org.jclouds.rackspace.cloudservers.binders; +package org.jclouds.rackspace.cloudservers.decorators; import static org.testng.Assert.assertEquals; @@ -40,54 +40,54 @@ import com.google.inject.Guice; import com.google.inject.Injector; /** - * Tests behavior of {@code RebootTypeBinder} + * Tests behavior of {@code AddRebootTypeAsJsonEntity} * * @author Adrian Cole */ -@Test(groups = "unit", testName = "cloudservers.RebootTypeBinderTest") -public class RebootTypeBinderTest { +@Test(groups = "unit", testName = "cloudservers.AddRebootTypeAsJsonEntityTest") +public class AddRebootTypeAsJsonEntityTest { Injector injector = Guice.createInjector(new ParserModule()); @Test(expectedExceptions = IllegalStateException.class) public void testPostIsIncorrect() { - RebootTypeBinder binder = new RebootTypeBinder(); + AddRebootTypeAsJsonEntity binder = new AddRebootTypeAsJsonEntity(); injector.injectMembers(binder); HttpRequest request = new HttpRequest(HttpMethod.POST, URI.create("http://localhost")); - binder.addEntityToRequest(ImmutableMap.of("adminPass", "foo"), request); + binder.decorateRequest(request, ImmutableMap.of("adminPass", "foo")); } @Test(expectedExceptions = IllegalArgumentException.class) public void testMustBeRebootType() { - RebootTypeBinder binder = new RebootTypeBinder(); + AddRebootTypeAsJsonEntity binder = new AddRebootTypeAsJsonEntity(); injector.injectMembers(binder); HttpRequest request = new HttpRequest(HttpMethod.POST, URI.create("http://localhost")); - binder.addEntityToRequest(new File("foo"), request); + binder.decorateRequest(request, new File("foo")); } @Test public void testHard() { - RebootTypeBinder binder = new RebootTypeBinder(); + AddRebootTypeAsJsonEntity binder = new AddRebootTypeAsJsonEntity(); injector.injectMembers(binder); HttpRequest request = new HttpRequest(HttpMethod.POST, URI.create("http://localhost")); - binder.addEntityToRequest(RebootType.HARD, request); + binder.decorateRequest(request, RebootType.HARD); assertEquals("{\"reboot\":{\"type\":\"HARD\"}}", request.getEntity()); } @Test public void testSoft() { - RebootTypeBinder binder = new RebootTypeBinder(); + AddRebootTypeAsJsonEntity binder = new AddRebootTypeAsJsonEntity(); injector.injectMembers(binder); HttpRequest request = new HttpRequest(HttpMethod.POST, URI.create("http://localhost")); - binder.addEntityToRequest(RebootType.SOFT, request); + binder.decorateRequest(request, RebootType.SOFT); assertEquals("{\"reboot\":{\"type\":\"SOFT\"}}", request.getEntity()); } @Test(expectedExceptions = { NullPointerException.class, IllegalStateException.class }) public void testNullIsBad() { - RebootTypeBinder binder = new RebootTypeBinder(); + AddRebootTypeAsJsonEntity binder = new AddRebootTypeAsJsonEntity(); injector.injectMembers(binder); HttpRequest request = new HttpRequest(HttpMethod.POST, URI.create("http://localhost")); - binder.addEntityToRequest(null, request); + binder.decorateRequest(request, null); } } diff --git a/rackspace/cloudservers/core/src/test/java/org/jclouds/rackspace/cloudservers/binders/ChangeServerNameBinderTest.java b/rackspace/cloudservers/core/src/test/java/org/jclouds/rackspace/cloudservers/decorators/AddServerNameAsJsonEntityTest.java similarity index 76% rename from rackspace/cloudservers/core/src/test/java/org/jclouds/rackspace/cloudservers/binders/ChangeServerNameBinderTest.java rename to rackspace/cloudservers/core/src/test/java/org/jclouds/rackspace/cloudservers/decorators/AddServerNameAsJsonEntityTest.java index 65ca666cd6..12e6bec5e3 100644 --- a/rackspace/cloudservers/core/src/test/java/org/jclouds/rackspace/cloudservers/binders/ChangeServerNameBinderTest.java +++ b/rackspace/cloudservers/core/src/test/java/org/jclouds/rackspace/cloudservers/decorators/AddServerNameAsJsonEntityTest.java @@ -21,7 +21,7 @@ * under the License. * ==================================================================== */ -package org.jclouds.rackspace.cloudservers.binders; +package org.jclouds.rackspace.cloudservers.decorators; import static org.testng.Assert.assertEquals; @@ -39,45 +39,45 @@ import com.google.inject.Guice; import com.google.inject.Injector; /** - * Tests behavior of {@code ChangeServerNameBinder} + * Tests behavior of {@code AddServerNameAsJsonEntity} * * @author Adrian Cole */ -@Test(groups = "unit", testName = "cloudservers.ChangeServerNameBinderTest") -public class ChangeServerNameBinderTest { +@Test(groups = "unit", testName = "cloudservers.AddServerNameAsJsonEntityTest") +public class AddServerNameAsJsonEntityTest { Injector injector = Guice.createInjector(new ParserModule()); @Test(expectedExceptions = IllegalStateException.class) public void testPostIsIncorrect() { - ChangeServerNameBinder binder = new ChangeServerNameBinder(); + AddServerNameAsJsonEntity binder = new AddServerNameAsJsonEntity(); injector.injectMembers(binder); HttpRequest request = new HttpRequest(HttpMethod.POST, URI.create("http://localhost")); - binder.addEntityToRequest(ImmutableMap.of("name", "foo"), request); + binder.decorateRequest(request, ImmutableMap.of("name", "foo")); } @Test(expectedExceptions = IllegalArgumentException.class) public void testMustBeString() { - ChangeServerNameBinder binder = new ChangeServerNameBinder(); + AddServerNameAsJsonEntity binder = new AddServerNameAsJsonEntity(); injector.injectMembers(binder); HttpRequest request = new HttpRequest(HttpMethod.POST, URI.create("http://localhost")); - binder.addEntityToRequest(new File("foo"), request); + binder.decorateRequest(request, new File("foo")); } @Test public void testCorrect() { - ChangeServerNameBinder binder = new ChangeServerNameBinder(); + AddServerNameAsJsonEntity binder = new AddServerNameAsJsonEntity(); injector.injectMembers(binder); HttpRequest request = new HttpRequest(HttpMethod.PUT, URI.create("http://localhost")); - binder.addEntityToRequest("foo", request); + binder.decorateRequest(request, "foo"); assertEquals("{\"server\":{\"name\":\"foo\"}}", request.getEntity()); } @Test(expectedExceptions = { NullPointerException.class, IllegalStateException.class }) public void testNullIsBad() { - ChangeServerNameBinder binder = new ChangeServerNameBinder(); + AddServerNameAsJsonEntity binder = new AddServerNameAsJsonEntity(); injector.injectMembers(binder); HttpRequest request = new HttpRequest(HttpMethod.PUT, URI.create("http://localhost")); - binder.addEntityToRequest(null, request); + binder.decorateRequest(request, null); } } diff --git a/rackspace/cloudservers/core/src/test/java/org/jclouds/rackspace/cloudservers/options/CreateServerOptionsTest.java b/rackspace/cloudservers/core/src/test/java/org/jclouds/rackspace/cloudservers/options/CreateServerOptionsTest.java index 02dcef1447..71871aec29 100644 --- a/rackspace/cloudservers/core/src/test/java/org/jclouds/rackspace/cloudservers/options/CreateServerOptionsTest.java +++ b/rackspace/cloudservers/core/src/test/java/org/jclouds/rackspace/cloudservers/options/CreateServerOptionsTest.java @@ -63,8 +63,8 @@ public class CreateServerOptionsTest { private HttpRequest buildRequest(CreateServerOptions options) { injector.injectMembers(options); HttpRequest request = new HttpRequest(HttpMethod.POST, URI.create("http://localhost")); - options.addEntityToRequest(ImmutableMap.of("name", "foo", "imageId", "1", "flavorId", "2"), - request); + options.decorateRequest(request, ImmutableMap.of("name", "foo", "imageId", "1", "flavorId", + "2")); return request; } diff --git a/rackspace/cloudservers/core/src/test/java/org/jclouds/rackspace/cloudservers/options/CreateSharedIpGroupOptionsTest.java b/rackspace/cloudservers/core/src/test/java/org/jclouds/rackspace/cloudservers/options/CreateSharedIpGroupOptionsTest.java index 86d12465b5..270245c654 100644 --- a/rackspace/cloudservers/core/src/test/java/org/jclouds/rackspace/cloudservers/options/CreateSharedIpGroupOptionsTest.java +++ b/rackspace/cloudservers/core/src/test/java/org/jclouds/rackspace/cloudservers/options/CreateSharedIpGroupOptionsTest.java @@ -58,7 +58,7 @@ public class CreateSharedIpGroupOptionsTest { private HttpRequest buildRequest(CreateSharedIpGroupOptions options) { injector.injectMembers(options); HttpRequest request = new HttpRequest(HttpMethod.POST, URI.create("http://localhost")); - options.addEntityToRequest(ImmutableMap.of("name", "foo"), request); + options.decorateRequest(request, ImmutableMap.of("name", "foo")); return request; } diff --git a/rackspace/cloudservers/core/src/test/java/org/jclouds/rackspace/cloudservers/options/RebuildServerOptionsTest.java b/rackspace/cloudservers/core/src/test/java/org/jclouds/rackspace/cloudservers/options/RebuildServerOptionsTest.java index 56e9d9ea40..a69ea2cdd2 100644 --- a/rackspace/cloudservers/core/src/test/java/org/jclouds/rackspace/cloudservers/options/RebuildServerOptionsTest.java +++ b/rackspace/cloudservers/core/src/test/java/org/jclouds/rackspace/cloudservers/options/RebuildServerOptionsTest.java @@ -58,7 +58,7 @@ public class RebuildServerOptionsTest { private HttpRequest buildRequest(RebuildServerOptions options) { injector.injectMembers(options); HttpRequest request = new HttpRequest(HttpMethod.POST, URI.create("http://localhost")); - options.addEntityToRequest(new HashMap(), request); + options.decorateRequest(request, new HashMap()); return request; } diff --git a/rackspace/core/src/main/java/org/jclouds/rackspace/RackspaceAuthentication.java b/rackspace/core/src/main/java/org/jclouds/rackspace/RackspaceAuthentication.java index 8cd8e630f8..46ef0b228d 100644 --- a/rackspace/core/src/main/java/org/jclouds/rackspace/RackspaceAuthentication.java +++ b/rackspace/core/src/main/java/org/jclouds/rackspace/RackspaceAuthentication.java @@ -31,8 +31,8 @@ import javax.ws.rs.Path; import org.jclouds.rackspace.functions.ParseAuthenticationResponseFromHeaders; import org.jclouds.rackspace.reference.RackspaceHeaders; -import org.jclouds.rest.Endpoint; -import org.jclouds.rest.ResponseParser; +import org.jclouds.rest.annotations.Endpoint; +import org.jclouds.rest.annotations.ResponseParser; /** * Provides access to Rackspace resources via their REST API. diff --git a/rackspace/core/src/test/java/org/jclouds/rackspace/RackspaceAuthenticationTest.java b/rackspace/core/src/test/java/org/jclouds/rackspace/RackspaceAuthenticationTest.java index 3d93cd469a..d68b057fa1 100644 --- a/rackspace/core/src/test/java/org/jclouds/rackspace/RackspaceAuthenticationTest.java +++ b/rackspace/core/src/test/java/org/jclouds/rackspace/RackspaceAuthenticationTest.java @@ -37,8 +37,8 @@ import org.jclouds.http.HttpRequest; import org.jclouds.http.config.JavaUrlHttpCommandExecutorServiceModule; import org.jclouds.rackspace.functions.ParseAuthenticationResponseFromHeaders; import org.jclouds.rackspace.reference.RackspaceHeaders; -import org.jclouds.rest.JaxrsAnnotationProcessor; -import org.jclouds.rest.config.JaxrsModule; +import org.jclouds.rest.config.RestModule; +import org.jclouds.rest.internal.RestAnnotationProcessor; import org.testng.annotations.BeforeClass; import org.testng.annotations.Test; @@ -56,7 +56,7 @@ import com.google.inject.TypeLiteral; @Test(groups = "unit", testName = "rackspace.RackspaceAuthentication") public class RackspaceAuthenticationTest { - private JaxrsAnnotationProcessor processor; + private RestAnnotationProcessor processor; public void testAuthenticate() throws SecurityException, NoSuchMethodException { Method method = RackspaceAuthentication.class.getMethod("authenticate", String.class, @@ -70,7 +70,7 @@ public class RackspaceAuthenticationTest { .singletonList("foo")); assertEquals(httpMethod.getHeaders().get(RackspaceHeaders.AUTH_KEY), Collections .singletonList("bar")); - assertEquals(JaxrsAnnotationProcessor.getParserOrThrowException(method), + assertEquals(RestAnnotationProcessor.getParserOrThrowException(method), ParseAuthenticationResponseFromHeaders.class); } @@ -83,10 +83,10 @@ public class RackspaceAuthenticationTest { bind(URI.class).annotatedWith(Authentication.class).toInstance( URI.create("http://localhost:8080")); } - }, new JaxrsModule(), new ExecutorServiceModule(new WithinThreadExecutorService()), + }, new RestModule(), new ExecutorServiceModule(new WithinThreadExecutorService()), new JavaUrlHttpCommandExecutorServiceModule()); processor = injector.getInstance(Key - .get(new TypeLiteral>() { + .get(new TypeLiteral>() { })); }