提交 1e6581f2 编写于 作者: P Prateek Srivastava 提交者: Jake Wharton

Supply method annotations to factory when invoking requestBodyConverter method.

上级 1c995b22
......@@ -35,9 +35,8 @@ final class StringConverterFactory extends Converter.Factory {
};
}
@Override
public Converter<?, RequestBody> requestBodyConverter(Type type, Annotation[] annotations,
Retrofit retrofit) {
@Override public Converter<?, RequestBody> requestBodyConverter(Type type,
Annotation[] parameterAnnotations, Annotation[] methodAnnotations, Retrofit retrofit) {
return new Converter<String, RequestBody>() {
@Override public RequestBody convert(String value) throws IOException {
return RequestBody.create(MediaType.parse("text/plain"), value);
......
......@@ -35,9 +35,8 @@ final class StringConverterFactory extends Converter.Factory {
};
}
@Override
public Converter<?, RequestBody> requestBodyConverter(Type type, Annotation[] annotations,
Retrofit retrofit) {
@Override public Converter<?, RequestBody> requestBodyConverter(Type type,
Annotation[] parameterAnnotations, Annotation[] methodAnnotations, Retrofit retrofit) {
return new Converter<String, RequestBody>() {
@Override public RequestBody convert(String value) throws IOException {
return RequestBody.create(MediaType.parse("text/plain"), value);
......
......@@ -36,7 +36,7 @@ final class StringConverterFactory extends Converter.Factory {
}
@Override public Converter<?, RequestBody> requestBodyConverter(Type type,
Annotation[] annotations, Retrofit retrofit) {
Annotation[] parameterAnnotations, Annotation[] methodAnnotations, Retrofit retrofit) {
return new Converter<String, RequestBody>() {
@Override public RequestBody convert(String value) throws IOException {
return RequestBody.create(MediaType.parse("text/plain"), value);
......
......@@ -65,8 +65,8 @@ public final class GsonConverterFactory extends Converter.Factory {
}
@Override
public Converter<?, RequestBody> requestBodyConverter(Type type, Annotation[] annotations,
Retrofit retrofit) {
public Converter<?, RequestBody> requestBodyConverter(Type type,
Annotation[] parameterAnnotations, Annotation[] methodAnnotations, Retrofit retrofit) {
TypeAdapter<?> adapter = gson.getAdapter(TypeToken.get(type));
return new GsonRequestBodyConverter<>(gson, adapter);
}
......
......@@ -61,8 +61,8 @@ public final class JacksonConverterFactory extends Converter.Factory {
}
@Override
public Converter<?, RequestBody> requestBodyConverter(Type type, Annotation[] annotations,
Retrofit retrofit) {
public Converter<?, RequestBody> requestBodyConverter(Type type,
Annotation[] parameterAnnotations, Annotation[] methodAnnotations, Retrofit retrofit) {
JavaType javaType = mapper.getTypeFactory().constructType(type);
ObjectWriter writer = mapper.writerWithType(javaType);
return new JacksonRequestBodyConverter<>(writer);
......
......@@ -58,8 +58,8 @@ public final class MoshiConverterFactory extends Converter.Factory {
}
@Override
public Converter<?, RequestBody> requestBodyConverter(Type type, Annotation[] annotations,
Retrofit retrofit) {
public Converter<?, RequestBody> requestBodyConverter(Type type,
Annotation[] parameterAnnotations, Annotation[] methodAnnotations, Retrofit retrofit) {
JsonAdapter<?> adapter = moshi.adapter(type);
return new MoshiRequestBodyConverter<>(adapter);
}
......
......@@ -60,8 +60,8 @@ public final class ProtoConverterFactory extends Converter.Factory {
}
@Override
public Converter<?, RequestBody> requestBodyConverter(Type type, Annotation[] annotations,
Retrofit retrofit) {
public Converter<?, RequestBody> requestBodyConverter(Type type,
Annotation[] parameterAnnotations, Annotation[] methodAnnotations, Retrofit retrofit) {
if (!(type instanceof Class<?>)) {
return null;
}
......
......@@ -43,9 +43,8 @@ public final class ScalarsConverterFactory extends Converter.Factory {
private ScalarsConverterFactory() {
}
@Override
public Converter<?, RequestBody> requestBodyConverter(Type type, Annotation[] annotations,
Retrofit retrofit) {
@Override public Converter<?, RequestBody> requestBodyConverter(Type type,
Annotation[] parameterAnnotations, Annotation[] methodAnnotations, Retrofit retrofit) {
if (type == String.class
|| type == boolean.class
|| type == Boolean.class
......
......@@ -75,8 +75,8 @@ public final class SimpleXmlConverterFactory extends Converter.Factory {
}
@Override
public Converter<?, RequestBody> requestBodyConverter(Type type, Annotation[] annotations,
Retrofit retrofit) {
public Converter<?, RequestBody> requestBodyConverter(Type type,
Annotation[] parameterAnnotations, Annotation[] methodAnnotations, Retrofit retrofit) {
if (!(type instanceof Class)) {
return null;
}
......
......@@ -53,8 +53,8 @@ public final class WireConverterFactory extends Converter.Factory {
}
@Override
public Converter<?, RequestBody> requestBodyConverter(Type type, Annotation[] annotations,
Retrofit retrofit) {
public Converter<?, RequestBody> requestBodyConverter(Type type,
Annotation[] parameterAnnotations, Annotation[] methodAnnotations, Retrofit retrofit) {
if (!(type instanceof Class<?>)) {
return null;
}
......
......@@ -39,8 +39,8 @@ final class BuiltInConverters extends Converter.Factory {
}
@Override
public Converter<?, RequestBody> requestBodyConverter(Type type, Annotation[] annotations,
Retrofit retrofit) {
public Converter<?, RequestBody> requestBodyConverter(Type type,
Annotation[] parameterAnnotations, Annotation[] methodAnnotations, Retrofit retrofit) {
if (RequestBody.class.isAssignableFrom(Types.getRawType(type))) {
return RequestBodyConverter.INSTANCE;
}
......
......@@ -57,8 +57,8 @@ public interface Converter<F, T> {
* specified by {@link Body @Body}, {@link Part @Part}, and {@link PartMap @PartMap}
* values.
*/
public Converter<?, RequestBody> requestBodyConverter(Type type, Annotation[] annotations,
Retrofit retrofit) {
public Converter<?, RequestBody> requestBodyConverter(Type type,
Annotation[] parameterAnnotations, Annotation[] methodAnnotations, Retrofit retrofit) {
return null;
}
......
......@@ -201,6 +201,7 @@ final class RequestFactoryParser {
private void parseParameters(Retrofit retrofit) {
Type[] methodParameterTypes = method.getGenericParameterTypes();
Annotation[] methodAnnotations = method.getAnnotations();
Annotation[][] methodParameterAnnotationArrays = method.getParameterAnnotations();
boolean gotField = false;
......@@ -429,16 +430,19 @@ final class RequestFactoryParser {
ParameterizedType parameterizedType = (ParameterizedType) methodParameterType;
Type iterableType = Utils.getParameterUpperBound(0, parameterizedType);
Converter<?, RequestBody> valueConverter =
retrofit.requestBodyConverter(iterableType, methodParameterAnnotations);
retrofit.requestBodyConverter(iterableType, methodParameterAnnotations,
methodAnnotations);
action = new RequestAction.Part<>(headers, valueConverter).iterable();
} else if (rawParameterType.isArray()) {
Class<?> arrayComponentType = boxIfPrimitive(rawParameterType.getComponentType());
Converter<?, RequestBody> valueConverter =
retrofit.requestBodyConverter(arrayComponentType, methodParameterAnnotations);
retrofit.requestBodyConverter(arrayComponentType, methodParameterAnnotations,
methodAnnotations);
action = new RequestAction.Part<>(headers, valueConverter).array();
} else {
Converter<?, RequestBody> valueConverter =
retrofit.requestBodyConverter(methodParameterType, methodParameterAnnotations);
retrofit.requestBodyConverter(methodParameterType, methodParameterAnnotations,
methodAnnotations);
action = new RequestAction.Part<>(headers, valueConverter);
}
......@@ -464,7 +468,8 @@ final class RequestFactoryParser {
}
Type valueType = Utils.getParameterUpperBound(1, parameterizedType);
Converter<?, RequestBody> valueConverter =
retrofit.requestBodyConverter(valueType, methodParameterAnnotations);
retrofit.requestBodyConverter(valueType, methodParameterAnnotations,
methodAnnotations);
PartMap partMap = (PartMap) methodParameterAnnotation;
action = new RequestAction.PartMap<>(valueConverter, partMap.encoding());
......@@ -482,7 +487,8 @@ final class RequestFactoryParser {
Converter<?, RequestBody> converter;
try {
converter =
retrofit.requestBodyConverter(methodParameterType, methodParameterAnnotations);
retrofit.requestBodyConverter(methodParameterType, methodParameterAnnotations,
methodAnnotations);
} catch (RuntimeException e) { // Wide exception range because factories are user code.
throw parameterError(e, i, "Unable to create @Body converter for %s",
methodParameterType);
......
......@@ -243,8 +243,9 @@ public final class Retrofit {
*
* @throws IllegalArgumentException if no converter available for {@code type}.
*/
public <T> Converter<T, RequestBody> requestBodyConverter(Type type, Annotation[] annotations) {
return nextRequestBodyConverter(null, type, annotations);
public <T> Converter<T, RequestBody> requestBodyConverter(Type type,
Annotation[] parameterAnnotations, Annotation[] methodAnnotations) {
return nextRequestBodyConverter(null, type, parameterAnnotations, methodAnnotations);
}
/**
......@@ -254,14 +255,16 @@ public final class Retrofit {
* @throws IllegalArgumentException if no converter available for {@code type}.
*/
public <T> Converter<T, RequestBody> nextRequestBodyConverter(Converter.Factory skipPast,
Type type, Annotation[] annotations) {
Type type, Annotation[] parameterAnnotations, Annotation[] methodAnnotations) {
checkNotNull(type, "type == null");
checkNotNull(annotations, "annotations == null");
checkNotNull(parameterAnnotations, "parameterAnnotations == null");
checkNotNull(methodAnnotations, "methodAnnotations == null");
int start = converterFactories.indexOf(skipPast) + 1;
for (int i = start, count = converterFactories.size(); i < count; i++) {
Converter.Factory factory = converterFactories.get(i);
Converter<?, RequestBody> converter =
converterFactories.get(i).requestBodyConverter(type, annotations, this);
factory.requestBodyConverter(type, parameterAnnotations, methodAnnotations, this);
if (converter != null) {
//noinspection unchecked
return (Converter<T, RequestBody>) converter;
......
......@@ -195,7 +195,8 @@ public final class CallTest {
.baseUrl(server.url("/"))
.addConverterFactory(new ToStringConverterFactory() {
@Override
public Converter<?, RequestBody> requestBodyConverter(Type type, Annotation[] annotations,
public Converter<?, RequestBody> requestBodyConverter(Type type,
Annotation[] parameterAnnotations, Annotation[] methodAnnotations,
Retrofit retrofit) {
return new Converter<String, RequestBody>() {
@Override public RequestBody convert(String value) throws IOException {
......@@ -221,7 +222,8 @@ public final class CallTest {
.baseUrl(server.url("/"))
.addConverterFactory(new ToStringConverterFactory() {
@Override
public Converter<?, RequestBody> requestBodyConverter(Type type, Annotation[] annotations,
public Converter<?, RequestBody> requestBodyConverter(Type type,
Annotation[] parameterAnnotations, Annotation[] methodAnnotations,
Retrofit retrofit) {
return new Converter<String, RequestBody>() {
@Override public RequestBody convert(String value) throws IOException {
......
......@@ -330,14 +330,18 @@ public final class RetrofitTest {
assertThat(annotations).hasAtLeastOneElementOfType(Annotated.Foo.class);
}
@Test public void parameterAnnotationsPassedToRequestBodyConverter() {
final AtomicReference<Annotation[]> annotationsRef = new AtomicReference<>();
@Test public void methodAndParameterAnnotationsPassedToRequestBodyConverter() {
final AtomicReference<Annotation[]> parameterAnnotationsRef = new AtomicReference<>();
final AtomicReference<Annotation[]> methodAnnotationsRef = new AtomicReference<>();
class MyConverterFactory extends Converter.Factory {
@Override
public Converter<?, RequestBody> requestBodyConverter(Type type, Annotation[] annotations,
Retrofit retrofit) {
annotationsRef.set(annotations);
return new ToStringConverterFactory().requestBodyConverter(type, annotations, retrofit);
public Converter<?, RequestBody> requestBodyConverter(Type type,
Annotation[] parameterAnnotations, Annotation[] methodAnnotations, Retrofit retrofit) {
parameterAnnotationsRef.set(parameterAnnotations);
methodAnnotationsRef.set(methodAnnotations);
return new ToStringConverterFactory().requestBodyConverter(type, parameterAnnotations,
methodAnnotations, retrofit);
}
}
Retrofit retrofit = new Retrofit.Builder()
......@@ -347,8 +351,8 @@ public final class RetrofitTest {
Annotated annotated = retrofit.create(Annotated.class);
annotated.bodyParameter(null); // Trigger internal setup.
Annotation[] annotations = annotationsRef.get();
assertThat(annotations).hasAtLeastOneElementOfType(Annotated.Foo.class);
assertThat(parameterAnnotationsRef.get()).hasAtLeastOneElementOfType(Annotated.Foo.class);
assertThat(methodAnnotationsRef.get()).hasAtLeastOneElementOfType(POST.class);
}
@Test public void parameterAnnotationsPassedToStringConverter() {
......@@ -786,7 +790,8 @@ public final class RetrofitTest {
@Test public void requestConverterFactoryQueried() {
Type type = String.class;
Annotation[] annotations = new Annotation[0];
Annotation[] parameterAnnotations = new Annotation[0];
Annotation[] methodAnnotations = new Annotation[1];
Converter<?, RequestBody> expectedAdapter = mock(Converter.class);
Converter.Factory factory = mock(Converter.Factory.class);
......@@ -796,12 +801,14 @@ public final class RetrofitTest {
.addConverterFactory(factory)
.build();
doReturn(expectedAdapter).when(factory).requestBodyConverter(type, annotations, retrofit);
doReturn(expectedAdapter).when(factory).requestBodyConverter(type, parameterAnnotations,
methodAnnotations, retrofit);
Converter<?, RequestBody> actualAdapter = retrofit.requestBodyConverter(type, annotations);
Converter<?, RequestBody> actualAdapter = retrofit.requestBodyConverter(type,
parameterAnnotations, methodAnnotations);
assertThat(actualAdapter).isSameAs(expectedAdapter);
verify(factory).requestBodyConverter(type, annotations, retrofit);
verify(factory).requestBodyConverter(type, parameterAnnotations, methodAnnotations, retrofit);
verifyNoMoreInteractions(factory);
}
......@@ -817,7 +824,7 @@ public final class RetrofitTest {
.build();
try {
retrofit.requestBodyConverter(type, annotations);
retrofit.requestBodyConverter(type, annotations, annotations);
fail();
} catch (IllegalArgumentException e) {
assertThat(e).hasMessage(""
......@@ -844,7 +851,7 @@ public final class RetrofitTest {
.build();
try {
retrofit.nextRequestBodyConverter(nonMatchingFactory1, type, annotations);
retrofit.nextRequestBodyConverter(nonMatchingFactory1, type, annotations, annotations);
fail();
} catch (IllegalArgumentException e) {
assertThat(e).hasMessage(""
......
......@@ -32,9 +32,8 @@ public final class NonMatchingConverterFactory extends Converter.Factory {
return null;
}
@Override
public Converter<?, RequestBody> requestBodyConverter(Type type, Annotation[] annotations,
Retrofit retrofit) {
@Override public Converter<?, RequestBody> requestBodyConverter(Type type,
Annotation[] parameterAnnotations, Annotation[] methodAnnotations, Retrofit retrofit) {
called = true;
return null;
}
......
......@@ -41,7 +41,7 @@ public class ToStringConverterFactory extends Converter.Factory {
}
@Override public Converter<?, RequestBody> requestBodyConverter(Type type,
Annotation[] annotations, Retrofit retrofit) {
Annotation[] parameterAnnotations, Annotation[] methodAnnotations, Retrofit retrofit) {
if (String.class.equals(type)) {
return new Converter<String, RequestBody>() {
@Override public RequestBody convert(String value) throws IOException {
......
......@@ -49,11 +49,11 @@ public final class ChunkingConverter {
*/
static class ChunkingConverterFactory extends Converter.Factory {
@Override
public Converter<?, RequestBody> requestBodyConverter(Type type, Annotation[] annotations,
Retrofit retrofit) {
public Converter<?, RequestBody> requestBodyConverter(Type type,
Annotation[] parameterAnnotations, Annotation[] methodAnnotations, Retrofit retrofit) {
boolean isBody = false;
boolean isChunked = false;
for (Annotation annotation : annotations) {
for (Annotation annotation : parameterAnnotations) {
isBody |= annotation instanceof Body;
isChunked |= annotation instanceof Chunked;
}
......@@ -63,7 +63,7 @@ public final class ChunkingConverter {
// Look up the real converter to delegate to.
final Converter<Object, RequestBody> delegate =
retrofit.nextRequestBodyConverter(this, type, annotations);
retrofit.nextRequestBodyConverter(this, type, parameterAnnotations, methodAnnotations);
// Wrap it in a Converter which removes the content length from the delegate's body.
return new Converter<Object, RequestBody>() {
@Override public RequestBody convert(Object value) throws IOException {
......
......@@ -74,15 +74,16 @@ public final class JsonAndXmlConverters {
return null;
}
@Override
public Converter<?, RequestBody> requestBodyConverter(Type type, Annotation[] annotations,
Retrofit retrofit) {
for (Annotation annotation : annotations) {
@Override public Converter<?, RequestBody> requestBodyConverter(Type type,
Annotation[] parameterAnnotations, Annotation[] methodAnnotations, Retrofit retrofit) {
for (Annotation annotation : parameterAnnotations) {
if (annotation instanceof Json) {
return jsonFactory.requestBodyConverter(type, annotations, retrofit);
return jsonFactory.requestBodyConverter(type, parameterAnnotations, methodAnnotations,
retrofit);
}
if (annotation instanceof Xml) {
return jsonFactory.requestBodyConverter(type, annotations, retrofit);
return xmlFactory.requestBodyConverter(type, parameterAnnotations, methodAnnotations,
retrofit);
}
}
return null;
......
......@@ -55,7 +55,7 @@ public final class JsonQueryParameters {
// you can call retrofit.requestBodyConverter(type, annotations) instead of having a
// reference to it explicitly as a field.
Converter<?, RequestBody> delegate =
delegateFactory.requestBodyConverter(type, annotations, retrofit);
delegateFactory.requestBodyConverter(type, annotations, new Annotation[0], retrofit);
return new DelegateToStringConverter<>(delegate);
}
}
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册