From feb0385c0a9a9f295ff6b39ed60de2878cabb2de Mon Sep 17 00:00:00 2001 From: "adrian.f.cole" Date: Tue, 21 Jul 2009 17:00:15 +0000 Subject: [PATCH] Issue 76: retyped PostBinder so that it can be used with PUTs that also need parameters git-svn-id: http://jclouds.googlecode.com/svn/trunk@1826 3d8758e0-26b5-11de-8745-db77d3ebf521 --- .../org/jclouds/http/binders/JsonBinder.java | 4 +- .../rest/JaxrsAnnotationProcessor.java | 34 +++++++-------- .../rest/{PostBinder.java => MapBinder.java} | 6 +-- ...EntityBinder.java => MapEntityBinder.java} | 4 +- .../{PostParam.java => MapEntityParam.java} | 4 +- .../jclouds/http/IntegrationTestClient.java | 8 ++-- .../rest/JaxrsAnnotationProcessorTest.java | 42 +++++++++++++++---- .../rackspace/options/BaseListOptions.java | 23 ++++++++++ .../options/BaseListOptionsTest.java | 23 ++++++++++ 9 files changed, 110 insertions(+), 38 deletions(-) rename core/src/main/java/org/jclouds/rest/{PostBinder.java => MapBinder.java} (89%) rename core/src/main/java/org/jclouds/rest/{PostEntityBinder.java => MapEntityBinder.java} (94%) rename core/src/main/java/org/jclouds/rest/{PostParam.java => MapEntityParam.java} (91%) diff --git a/core/src/main/java/org/jclouds/http/binders/JsonBinder.java b/core/src/main/java/org/jclouds/http/binders/JsonBinder.java index cce3f3199a..9302b747d2 100644 --- a/core/src/main/java/org/jclouds/http/binders/JsonBinder.java +++ b/core/src/main/java/org/jclouds/http/binders/JsonBinder.java @@ -32,7 +32,7 @@ import javax.ws.rs.core.HttpHeaders; import javax.ws.rs.core.MediaType; import org.jclouds.http.HttpRequest; -import org.jclouds.rest.PostEntityBinder; +import org.jclouds.rest.MapEntityBinder; import com.google.gson.Gson; import com.google.inject.Inject; @@ -43,7 +43,7 @@ import com.google.inject.Inject; * @author Adrian Cole * @since 4.0 */ -public class JsonBinder implements PostEntityBinder { +public class JsonBinder implements MapEntityBinder { @Inject protected Gson gson; diff --git a/core/src/main/java/org/jclouds/rest/JaxrsAnnotationProcessor.java b/core/src/main/java/org/jclouds/rest/JaxrsAnnotationProcessor.java index 42f4649021..4ab491bd16 100644 --- a/core/src/main/java/org/jclouds/rest/JaxrsAnnotationProcessor.java +++ b/core/src/main/java/org/jclouds/rest/JaxrsAnnotationProcessor.java @@ -89,7 +89,7 @@ public class JaxrsAnnotationProcessor { private final Map>> methodToIndexOfParamToHeaderParamAnnotations = createMethodToIndexOfParamToAnnotation(HeaderParam.class); private final Map>> methodToIndexOfParamToHostPrefixParamAnnotations = createMethodToIndexOfParamToAnnotation(HostPrefixParam.class); private final Map>> methodToindexOfParamToPathParamAnnotations = createMethodToIndexOfParamToAnnotation(PathParam.class); - private final Map>> methodToindexOfParamToPostParamAnnotations = createMethodToIndexOfParamToAnnotation(PostParam.class); + private final Map>> methodToindexOfParamToPostParamAnnotations = createMethodToIndexOfParamToAnnotation(MapEntityParam.class); private final Map>> methodToindexOfParamToParamParserAnnotations = createMethodToIndexOfParamToAnnotation(ParamParser.class); static Map>> createMethodToIndexOfParamToAnnotation( @@ -323,31 +323,31 @@ public class JaxrsAnnotationProcessor { return null; } - public PostEntityBinder getPostEntityBinderOrNull(Method method, Object[] args) { + public MapEntityBinder getMapEntityBinderOrNull(Method method, Object[] args) { 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 PostEntityBinder) { - PostEntityBinder binder = (PostEntityBinder) postBinders[0]; + if (postBinders[0] instanceof MapEntityBinder) { + MapEntityBinder binder = (MapEntityBinder) postBinders[0]; injector.injectMembers(binder); return binder; } } else { - if (postBinders[0] instanceof PostEntityBinder) { + if (postBinders[0] instanceof MapEntityBinder) { throw new IllegalArgumentException( "we currently do not support multiple varargs postBinders in: " + method.getName()); } } - } else if (arg instanceof PostEntityBinder) { - PostEntityBinder binder = (PostEntityBinder) arg; + } else if (arg instanceof MapEntityBinder) { + MapEntityBinder binder = (MapEntityBinder) arg; injector.injectMembers(binder); return binder; } } - PostBinder annotation = method.getAnnotation(PostBinder.class); + MapBinder annotation = method.getAnnotation(MapBinder.class); if (annotation != null) { return injector.getInstance(annotation.value()); } @@ -392,17 +392,17 @@ public class JaxrsAnnotationProcessor { HttpRequest request) { switch (request.getMethod()) { case POST: - PostEntityBinder postBinder = null; - Map postParams = buildPostParams(method, args); - // post binder is only useful if there are parameters. We guard here in case the - // PostEntityBinder is also an EntityBinder. If so, it can be used with or without + case PUT: + MapEntityBinder mapBinder = null; + 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 (postParams.size() > 0 - && (postBinder = this.getPostEntityBinderOrNull(method, args)) != null) { - postBinder.addEntityToRequest(postParams, request); + if (mapParams.size() > 0 + && (mapBinder = this.getMapEntityBinderOrNull(method, args)) != null) { + mapBinder.addEntityToRequest(mapParams, request); break; } - case PUT: HttpRequestOptions options = findOptionsIn(method, args); if (options != null) { optionsBinder.addEntityToRequest(options, request); @@ -568,7 +568,7 @@ public class JaxrsAnnotationProcessor { postParams.put(((PathParam) key).value(), injector.getInstance(extractor.value()) .apply(args[entry.getKey()])); } else { - String paramKey = ((PostParam) key).value(); + String paramKey = ((MapEntityParam) key).value(); String paramValue = args[entry.getKey()].toString(); postParams.put(paramKey, paramValue); } diff --git a/core/src/main/java/org/jclouds/rest/PostBinder.java b/core/src/main/java/org/jclouds/rest/MapBinder.java similarity index 89% rename from core/src/main/java/org/jclouds/rest/PostBinder.java rename to core/src/main/java/org/jclouds/rest/MapBinder.java index 64ef89cede..3c8b8059ae 100644 --- a/core/src/main/java/org/jclouds/rest/PostBinder.java +++ b/core/src/main/java/org/jclouds/rest/MapBinder.java @@ -36,11 +36,11 @@ import java.lang.annotation.Target; */ @Target(METHOD) @Retention(RUNTIME) -public @interface PostBinder { +public @interface MapBinder { /** - * How to bind {@link PostParam} values, if there is no {@link PostEntityBinder} in the method + * How to bind {@link MapEntityParam} values, if there is no {@link MapEntityBinder} in the method * definition */ - Class value(); + Class value(); } diff --git a/core/src/main/java/org/jclouds/rest/PostEntityBinder.java b/core/src/main/java/org/jclouds/rest/MapEntityBinder.java similarity index 94% rename from core/src/main/java/org/jclouds/rest/PostEntityBinder.java rename to core/src/main/java/org/jclouds/rest/MapEntityBinder.java index 499d31538d..6cbc0cbff8 100644 --- a/core/src/main/java/org/jclouds/rest/PostEntityBinder.java +++ b/core/src/main/java/org/jclouds/rest/MapEntityBinder.java @@ -33,12 +33,12 @@ import org.jclouds.http.HttpRequest; * @author Adrian Cole * */ -public interface PostEntityBinder extends EntityBinder { +public interface MapEntityBinder extends EntityBinder { /** * creates and binds the POST entity to the request using parameters specified. * - * @see PostParam + * @see MapEntityParam */ public void addEntityToRequest(Map postParams, HttpRequest request); diff --git a/core/src/main/java/org/jclouds/rest/PostParam.java b/core/src/main/java/org/jclouds/rest/MapEntityParam.java similarity index 91% rename from core/src/main/java/org/jclouds/rest/PostParam.java rename to core/src/main/java/org/jclouds/rest/MapEntityParam.java index 0209b4543e..2e4e0e56c1 100644 --- a/core/src/main/java/org/jclouds/rest/PostParam.java +++ b/core/src/main/java/org/jclouds/rest/MapEntityParam.java @@ -36,10 +36,10 @@ import java.lang.annotation.Target; */ @Target(PARAMETER) @Retention(RUNTIME) -public @interface PostParam { +public @interface MapEntityParam { /** - * The key used in a map passed to the {@link PostEntityBinder} associated with the request. + * The key used in a map passed to the {@link MapEntityBinder} associated with the request. */ String value(); } diff --git a/core/src/test/java/org/jclouds/http/IntegrationTestClient.java b/core/src/test/java/org/jclouds/http/IntegrationTestClient.java index bdc26e4a8a..f7d6daa2a7 100644 --- a/core/src/test/java/org/jclouds/http/IntegrationTestClient.java +++ b/core/src/test/java/org/jclouds/http/IntegrationTestClient.java @@ -38,8 +38,8 @@ import org.jclouds.http.functions.ParseSax; import org.jclouds.http.options.HttpRequestOptions; import org.jclouds.rest.EntityParam; import org.jclouds.rest.ExceptionParser; -import org.jclouds.rest.PostBinder; -import org.jclouds.rest.PostParam; +import org.jclouds.rest.MapBinder; +import org.jclouds.rest.MapEntityParam; import org.jclouds.rest.RequestFilters; import org.jclouds.rest.XMLResponseParser; @@ -92,8 +92,8 @@ public interface IntegrationTestClient { @POST @Path("objects/{id}") - @PostBinder(JsonBinder.class) - Future postJson(@PathParam("id") String id, @PostParam("key") String toPut); + @MapBinder(JsonBinder.class) + Future postJson(@PathParam("id") String id, @MapEntityParam("key") String toPut); @GET @Path("objects/{id}") diff --git a/core/src/test/java/org/jclouds/rest/JaxrsAnnotationProcessorTest.java b/core/src/test/java/org/jclouds/rest/JaxrsAnnotationProcessorTest.java index c3b1d7b25f..3335192f32 100644 --- a/core/src/test/java/org/jclouds/rest/JaxrsAnnotationProcessorTest.java +++ b/core/src/test/java/org/jclouds/rest/JaxrsAnnotationProcessorTest.java @@ -89,14 +89,14 @@ public class JaxrsAnnotationProcessorTest { @POST @Path("{foo}") - public void postWithPath(@PathParam("foo") @PostParam("fooble") String path, - PostEntityBinder content) { + public void postWithPath(@PathParam("foo") @MapEntityParam("fooble") String path, + MapEntityBinder content) { } @POST @Path("{foo}") - @PostBinder(JsonBinder.class) - public void postWithMethodBinder(@PathParam("foo") @PostParam("fooble") String path) { + @MapBinder(JsonBinder.class) + public void postWithMethodBinder(@PathParam("foo") @MapEntityParam("fooble") String path) { } } @@ -134,11 +134,10 @@ public class JaxrsAnnotationProcessorTest { } public void testCreatePostWithPathRequest() throws SecurityException, NoSuchMethodException { - Method method = TestPost.class - .getMethod("postWithPath", String.class, PostEntityBinder.class); + Method method = TestPost.class.getMethod("postWithPath", String.class, MapEntityBinder.class); URI endpoint = URI.create("http://localhost"); HttpRequest httpMethod = factory.create(TestPost.class).createRequest(endpoint, method, - new Object[] { "data", new PostEntityBinder() { + new Object[] { "data", new MapEntityBinder() { public void addEntityToRequest(Map postParams, HttpRequest request) { request.setEntity(postParams.get("fooble")); @@ -173,6 +172,33 @@ public class JaxrsAnnotationProcessorTest { assertEquals(httpMethod.getEntity(), expected); } + public class TestPut { + + @PUT + @Path("{foo}") + @MapBinder(JsonBinder.class) + public void putWithMethodBinder(@PathParam("foo") @MapEntityParam("fooble") String path) { + } + + } + + public void testCreatePutWithMethodBinder() throws SecurityException, NoSuchMethodException { + Method method = TestPut.class.getMethod("putWithMethodBinder", String.class); + URI endpoint = URI.create("http://localhost"); + HttpRequest httpMethod = factory.create(TestPut.class).createRequest(endpoint, 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("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 void filter(HttpRequest request) throws HttpException { @@ -446,7 +472,7 @@ public class JaxrsAnnotationProcessorTest { NoSuchMethodException { DateTime date = new DateTime(); GetOptions options = GetOptions.Builder.ifModifiedSince(date); - HttpRequestOptions[] optionsHolder = new HttpRequestOptions[]{}; + HttpRequestOptions[] optionsHolder = new HttpRequestOptions[] {}; Method method = TestRequest.class.getMethod("get", String.class, optionsHolder.getClass()); URI endpoint = URI.create("http://localhost"); HttpRequest httpMethod = factory.create(TestRequest.class).createRequest(endpoint, method, diff --git a/rackspace/core/src/main/java/org/jclouds/rackspace/options/BaseListOptions.java b/rackspace/core/src/main/java/org/jclouds/rackspace/options/BaseListOptions.java index a8046071ed..635a345e33 100644 --- a/rackspace/core/src/main/java/org/jclouds/rackspace/options/BaseListOptions.java +++ b/rackspace/core/src/main/java/org/jclouds/rackspace/options/BaseListOptions.java @@ -1,3 +1,26 @@ +/** + * + * 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.rackspace.options; import static com.google.common.base.Preconditions.checkNotNull; diff --git a/rackspace/core/src/test/java/org/jclouds/rackspace/options/BaseListOptionsTest.java b/rackspace/core/src/test/java/org/jclouds/rackspace/options/BaseListOptionsTest.java index 1ec82c7dc4..95b634cbb7 100644 --- a/rackspace/core/src/test/java/org/jclouds/rackspace/options/BaseListOptionsTest.java +++ b/rackspace/core/src/test/java/org/jclouds/rackspace/options/BaseListOptionsTest.java @@ -1,3 +1,26 @@ +/** + * + * 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.rackspace.options; import static org.jclouds.rackspace.options.BaseListOptions.Builder.changesSince;