added endpoint parser that can collaborate with multiple parameters

This commit is contained in:
Adrian Cole 2010-08-09 01:26:59 -07:00
parent 10c2a0e36b
commit 1ec0c40c95
2 changed files with 282 additions and 209 deletions

View File

@ -613,13 +613,15 @@ public class RestAnnotationProcessor<T> {
}
@VisibleForTesting
public static URI getEndpointInParametersOrNull(Method method, Object[] args, Injector injector) {
Map<Integer, Set<Annotation>> map = RestAnnotationProcessor.indexWithOnlyOneAnnotation(method, "@EndpointParam",
RestAnnotationProcessor.methodToIndexOfParamToEndpointParamAnnotations);
if (map.size() == 1 && args.length > 0) {
EndpointParam annotation = (EndpointParam) map.values().iterator().next().iterator().next();
public static URI getEndpointInParametersOrNull(Method method, final Object[] args, Injector injector) {
Map<Integer, Set<Annotation>> map = indexWithAtLeastOneAnnotation(method,
methodToIndexOfParamToEndpointParamAnnotations);
if (map.size() >= 1 && args.length > 0) {
EndpointParam firstAnnotation = (EndpointParam) Iterables.get(Iterables.get(map.values(), 0), 0);
Function<Object, URI> parser = injector.getInstance(firstAnnotation.parser());
if (map.size() == 1) {
int index = map.keySet().iterator().next();
Function<Object, URI> parser = injector.getInstance(annotation.parser());
try {
URI returnVal = parser.apply(args[index]);
checkArgument(returnVal != null, String.format("endpoint for [%s] not configured for %s", args[index],
@ -628,6 +630,25 @@ public class RestAnnotationProcessor<T> {
} catch (NullPointerException e) {
throw new IllegalArgumentException(String.format("argument at index %d on method %s", index, method), e);
}
} else {
Iterable<Object> argsToParse = Iterables.transform(map.keySet(), new Function<Integer, Object>() {
@Override
public Object apply(Integer from) {
return args[from];
}
});
try {
URI returnVal = parser.apply(argsToParse);
checkArgument(returnVal != null, String.format("endpoint for [%s] not configured for %s", argsToParse,
method));
return returnVal;
} catch (NullPointerException e) {
throw new IllegalArgumentException(String.format("argument at indexes %s on method %s", map.keySet(),
method), e);
}
}
}
return null;
}
@ -831,18 +852,23 @@ public class RestAnnotationProcessor<T> {
public static Map<Integer, Set<Annotation>> indexWithOnlyOneAnnotation(Method method, String description,
Map<Method, Map<Integer, Set<Annotation>>> toRefine) {
Map<Integer, Set<Annotation>> indexToPayloadAnnotation = indexWithAtLeastOneAnnotation(method, toRefine);
if (indexToPayloadAnnotation.size() > 1) {
throw new IllegalStateException(String.format(
"You must not specify more than one %s annotation on: %s; found %s", description, method.toString(),
indexToPayloadAnnotation));
}
return indexToPayloadAnnotation;
}
private static Map<Integer, Set<Annotation>> indexWithAtLeastOneAnnotation(Method method,
Map<Method, Map<Integer, Set<Annotation>>> toRefine) {
Map<Integer, Set<Annotation>> indexToPayloadAnnotation = filterValues(toRefine.get(method),
new Predicate<Set<Annotation>>() {
public boolean apply(Set<Annotation> input) {
return input.size() == 1;
}
});
if (indexToPayloadAnnotation.size() > 1) {
throw new IllegalStateException(String.format(
"You must not specify more than one %s annotation on: %s; found %s", description, method.toString(),
indexToPayloadAnnotation));
}
return indexToPayloadAnnotation;
}

View File

@ -60,6 +60,7 @@ import javax.annotation.Nullable;
import javax.inject.Named;
import javax.inject.Provider;
import javax.inject.Qualifier;
import javax.inject.Singleton;
import javax.ws.rs.Consumes;
import javax.ws.rs.FormParam;
import javax.ws.rs.GET;
@ -138,6 +139,7 @@ import org.testng.annotations.DataProvider;
import org.testng.annotations.Test;
import com.google.common.base.Function;
import com.google.common.base.Joiner;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableMultimap;
import com.google.common.collect.ImmutableSet;
@ -1786,22 +1788,18 @@ public class RestAnnotationProcessorTest extends BaseRestClientTest {
factory(TestVirtualHost.class).createRequest(method, "1", "");
}
public class TestHeaders {
public interface TestHeaders {
@GET
public void oneHeader(@HeaderParam("header") String header) {
}
void oneHeader(@HeaderParam("header") String header);
@GET
public void oneIntHeader(@HeaderParam("header") int header) {
}
void oneIntHeader(@HeaderParam("header") int header);
@GET
public void twoDifferentHeaders(@HeaderParam("header1") String header1, @HeaderParam("header2") String header2) {
}
void twoDifferentHeaders(@HeaderParam("header1") String header1, @HeaderParam("header2") String header2);
@GET
public void twoSameHeaders(@HeaderParam("header") String header1, @HeaderParam("header") String header2) {
}
void twoSameHeaders(@HeaderParam("header") String header1, @HeaderParam("header") String header2);
}
@Test
@ -1843,6 +1841,56 @@ public class RestAnnotationProcessorTest extends BaseRestClientTest {
assert values.contains("egg");
}
public interface TestEndpointParams {
@GET
void oneEndpointParam(@EndpointParam(parser = ConvertToURI.class) String EndpointParam);
@Singleton
public static class ConvertToURI implements Function<Object, URI> {
@Override
public URI apply(Object from) {
return URI.create(from.toString());
}
}
@GET
void twoEndpointParams(@EndpointParam(parser = ConvertTwoToURI.class) String EndpointParam1,
@EndpointParam(parser = ConvertTwoToURI.class) String EndpointParam2);
@Singleton
public static class ConvertTwoToURI implements Function<Object, URI> {
@SuppressWarnings("unchecked")
@Override
public URI apply(Object from) {
return URI.create(Joiner.on('/').join((Iterable<Object>) from));
}
}
}
@SuppressWarnings("static-access")
@Test
public void testOneEndpointParam() throws SecurityException, NoSuchMethodException {
Method method = TestEndpointParams.class.getMethod("oneEndpointParam", String.class);
URI uri = factory(TestEndpointParams.class).getEndpointInParametersOrNull(method, new Object[] { "robot" },
injector);
assertEquals(uri, URI.create("robot"));
}
@SuppressWarnings("static-access")
@Test
public void testTwoDifferentEndpointParams() throws SecurityException, NoSuchMethodException {
Method method = TestEndpointParams.class.getMethod("twoEndpointParams", String.class, String.class);
URI uri = factory(TestEndpointParams.class).getEndpointInParametersOrNull(method,
new Object[] { "robot", "egg" }, injector);
assertEquals(uri, URI.create("robot/egg"));
}
public interface TestPayload {
@PUT
public void put(@BinderParam(BindToStringPayload.class) String content);
@ -1975,8 +2023,7 @@ public class RestAnnotationProcessorTest extends BaseRestClientTest {
@Override
protected void configure() {
bind(URI.class).annotatedWith(Localhost2.class).toInstance(
URI.create("http://localhost:1111"));
bind(URI.class).annotatedWith(Localhost2.class).toInstance(URI.create("http://localhost:1111"));
}
}));