From 02dd27ef31ef161cefaf7bcf646bc396ecd16b08 Mon Sep 17 00:00:00 2001 From: adriancole Date: Mon, 8 Jul 2013 12:19:12 -0700 Subject: [PATCH] refactor MethodHandler to be extensible --- .../src/main/java/feign/MethodHandler.java | 87 ++++++++++--------- 1 file changed, 47 insertions(+), 40 deletions(-) diff --git a/feign-core/src/main/java/feign/MethodHandler.java b/feign-core/src/main/java/feign/MethodHandler.java index a643179e29..9d71170d8c 100644 --- a/feign-core/src/main/java/feign/MethodHandler.java +++ b/feign-core/src/main/java/feign/MethodHandler.java @@ -16,7 +16,6 @@ package feign; import java.io.IOException; -import java.lang.reflect.Type; import javax.inject.Inject; import javax.inject.Provider; @@ -30,7 +29,7 @@ import static feign.Util.checkNotNull; import static feign.Util.ensureClosed; -final class MethodHandler { +abstract class MethodHandler { /** * Those using guava will implement as {@code Function}. @@ -53,25 +52,41 @@ static class Factory { public MethodHandler create(Target target, MethodMetadata md, BuildTemplateFromArgs buildTemplateFromArgs, Options options, Decoder decoder, ErrorDecoder errorDecoder) { - return new MethodHandler(target, client, retryer, wire, md, buildTemplateFromArgs, options, decoder, errorDecoder); + return new SynchronousMethodHandler(target, client, retryer, wire, md, buildTemplateFromArgs, options, decoder, errorDecoder); } } - private final MethodMetadata metadata; - private final Target target; - private final Client client; - private final Provider retryer; - private final Wire wire; - - private final BuildTemplateFromArgs buildTemplateFromArgs; - private final Options options; - private final Decoder decoder; - private final ErrorDecoder errorDecoder; - - // cannot inject wildcards in dagger - @SuppressWarnings("rawtypes") - private MethodHandler(Target target, Client client, Provider retryer, Wire wire, MethodMetadata metadata, - BuildTemplateFromArgs buildTemplateFromArgs, Options options, Decoder decoder, ErrorDecoder errorDecoder) { + static final class SynchronousMethodHandler extends MethodHandler { + private final Decoder decoder; + + private SynchronousMethodHandler(Target target, Client client, Provider retryer, Wire wire, MethodMetadata metadata, + BuildTemplateFromArgs buildTemplateFromArgs, Options options, Decoder decoder, ErrorDecoder errorDecoder) { + super(target, client, retryer, wire, metadata, buildTemplateFromArgs, options, errorDecoder); + this.decoder = checkNotNull(decoder, "decoder for %s", target); + } + + @Override protected Object decode(Object[] argv, Response response) throws Throwable { + if (metadata.returnType().equals(Response.class)) { + return response; + } else if (metadata.returnType() == void.class) { + return null; + } + return decoder.decode(metadata.configKey(), response, metadata.returnType()); + } + } + + protected final MethodMetadata metadata; + protected final Target target; + protected final Client client; + protected final Provider retryer; + protected final Wire wire; + + protected final BuildTemplateFromArgs buildTemplateFromArgs; + protected final Options options; + protected final ErrorDecoder errorDecoder; + + private MethodHandler(Target target, Client client, Provider retryer, Wire wire, MethodMetadata metadata, + BuildTemplateFromArgs buildTemplateFromArgs, Options options, ErrorDecoder errorDecoder) { this.target = checkNotNull(target, "target"); this.client = checkNotNull(client, "client for %s", target); this.retryer = checkNotNull(retryer, "retryer for %s", target); @@ -79,7 +94,6 @@ private MethodHandler(Target target, Client client, Provider retryer, W this.metadata = checkNotNull(metadata, "metadata for %s", target); this.buildTemplateFromArgs = checkNotNull(buildTemplateFromArgs, "metadata for %s", target); this.options = checkNotNull(options, "options for %s", target); - this.decoder = checkNotNull(decoder, "decoder for %s", target); this.errorDecoder = checkNotNull(errorDecoder, "errorDecoder for %s", target); } @@ -88,7 +102,7 @@ public Object invoke(Object[] argv) throws Throwable { Retryer retryer = this.retryer.get(); while (true) { try { - return executeAndDecode(metadata.configKey(), template, metadata.returnType()); + return executeAndDecode(argv, template); } catch (RetryableException e) { retryer.continueOrPropagate(e); continue; @@ -96,37 +110,30 @@ public Object invoke(Object[] argv) throws Throwable { } } - public Object executeAndDecode(String configKey, RequestTemplate template, Type returnType) + public Object executeAndDecode(Object[] argv, RequestTemplate template) throws Throwable { // create the request from a mutable copy of the input template. Request request = target.apply(new RequestTemplate(template)); wire.wireRequest(target, request); - Response response = execute(request); + Response response; + try { + response = client.execute(request, options); + } catch (IOException e) { + throw errorExecuting(request, e); + } try { response = wire.wireAndRebufferResponse(target, response); if (response.status() >= 200 && response.status() < 300) { - if (returnType.equals(Response.class)) { - return response; - } else if (returnType == void.class) { - return null; - } - return decoder.decode(configKey, response, returnType); + return decode(argv, response); } else { - throw errorDecoder.decode(configKey, response); + throw errorDecoder.decode(metadata.configKey(), response); } - } catch (Throwable e) { + } catch (IOException e) { + throw errorReading(request, response, e); + } finally { ensureClosed(response.body()); - if (IOException.class.isInstance(e)) - throw errorReading(request, response, IOException.class.cast(e)); - throw e; } } - private Response execute(Request request) { - try { - return client.execute(request, options); - } catch (IOException e) { - throw errorExecuting(request, e); - } - } + protected abstract Object decode(Object[] argv, Response response) throws Throwable; }