/* * Copyright 2013 Netflix, Inc. * * Licensed 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 feign; import com.google.common.base.Optional; import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableMap; import java.lang.reflect.Method; import java.util.Map; import javax.net.ssl.SSLSocketFactory; import dagger.ObjectGraph; import dagger.Provides; import feign.Request.Options; import feign.Target.HardCodedTarget; import feign.Wire.NoOpWire; import feign.codec.BodyEncoder; import feign.codec.Decoder; import feign.codec.ErrorDecoder; import feign.codec.FormEncoder; /** * Feign's purpose is to ease development against http apis that feign * restfulness. *

* In implementation, Feign is a {@link Feign#newInstance factory} for * generating {@link Target targeted} http apis. */ public abstract class Feign { /** * Returns a new instance of an HTTP API, defined by annotations in the * {@link Feign Contract}, for the specified {@code target}. You should * cache this result. */ public abstract T newInstance(Target target); public static T create(Class apiType, String url, Object... modules) { return create(new HardCodedTarget(apiType, url), modules); } /** * Shortcut to {@link #newInstance(Target) create} a single {@code targeted} * http api using {@link ReflectiveFeign reflection}. */ public static T create(Target target, Object... modules) { return create(modules).newInstance(target); } /** * Returns a {@link ReflectiveFeign reflective} factory for generating * {@link Target targeted} http apis. */ public static Feign create(Object... modules) { Object[] modulesForGraph = ImmutableList.builder() // .add(new Defaults()) // .add(new ReflectiveFeign.Module()) // .add(Optional.fromNullable(modules).or(new Object[]{})).build().toArray(); return ObjectGraph.create(modulesForGraph).get(Feign.class); } /** * Returns an {@link ObjectGraph Dagger ObjectGraph} that can inject a * {@link ReflectiveFeign reflective} Feign. */ public static ObjectGraph createObjectGraph(Object... modules) { Object[] modulesForGraph = ImmutableList.builder() // .add(new Defaults()) // .add(new ReflectiveFeign.Module()) // .add(Optional.fromNullable(modules).or(new Object[]{})).build().toArray(); return ObjectGraph.create(modulesForGraph); } @dagger.Module(complete = false, injects = Feign.class, library = true) public static class Defaults { @Provides SSLSocketFactory sslSocketFactory() { return SSLSocketFactory.class.cast(SSLSocketFactory.getDefault()); } @Provides Client httpClient(Client.Default client) { return client; } @Provides Retryer retryer() { return new Retryer.Default(); } @Provides Wire noOp() { return new NoOpWire(); } @Provides Map noOptions() { return ImmutableMap.of(); } @Provides Map noBodyEncoders() { return ImmutableMap.of(); } @Provides Map noFormEncoders() { return ImmutableMap.of(); } @Provides Map noDecoders() { return ImmutableMap.of(); } @Provides Map noErrorDecoders() { return ImmutableMap.of(); } } /** *

* Configuration keys are formatted as unresolved see tags. *

* For example. *

*

* Note that there is no whitespace expected in a key! */ public static String configKey(Method method) { StringBuilder builder = new StringBuilder(); builder.append(method.getDeclaringClass().getSimpleName()); builder.append('#').append(method.getName()).append('('); for (Class param : method.getParameterTypes()) builder.append(param.getSimpleName()).append(','); if (method.getParameterTypes().length > 0) builder.deleteCharAt(builder.length() - 1); return builder.append(')').toString(); } Feign() { } }