/**
* Copyright (C) 2010-2016 eBusiness Information, Excilys Group
*
* 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 org.androidannotations.rest.spring.annotations;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* <p>
* Apply @{@link Rest} on an interface to create a RestService class that will
* contain implementation of rest calls related to the methods you define in the
* interface.
* </p>
* <p>
* You should then inject your RestService class by using {@link RestService}
* annotation in any enhanced classes.
* </p>
* <p>
* <b>Note:</b> Implementation is based on <a href=
* "http://docs.spring.io/spring-android/docs/current/reference/htmlsingle/"
* >Spring Android Rest-template</a> library. So you <b>MUST</b> have the
* library in your classpath and we highly recommend you to take some time to
* read this document and understand how the library works.
* </p>
*
*
* <h1>Converters</h1>
* <p>
* Every {@link Rest} annotated interface MUST define at least one
* {@link #converters()} to tell the library how to convert received data into
* Java objects.
* </p>
* <p>
* {@link #converters()} value MAY contain one or several
* {@link org.springframework.http.converter.HttpMessageConverter} sub-classes
* </p>
* <blockquote>
*
* <b>Example :</b> The following RestClient will use <a
* href="http://jackson.codehaus.org/">Jackson</a> to deserialize received data
* as Java objects.
*
* <pre>
* @Rest(<b>converters</b> = MappingJackson2HttpMessageConverter.class)
* public interface RestClient {
*
* @Get("http://myserver/events")
* EventList getEvents();
* }
* </pre>
*
* </blockquote>
*
*
* <h1>Root url</h1>
* <p>
* If you don't wan't to repeat the root URL in each method, you MAY like the
* {@link #rootUrl()} field. It let you define a common root URL which will be
* prefixed on every method of your RestClient.
* </p>
*
* <blockquote>
*
* <b>Example :</b>
*
* <pre>
* @Rest(<b>rootUrl</b> = "http://myserver", converters = MappingJackson2HttpMessageConverter.class)
* public interface RestClient {
*
* @Get("/events")
* EventList getEvents();
*
* @Get("/lastevent")
* Event getLastEvent();
* }
* </pre>
*
* </blockquote>
*
*
* <h1>Interceptors</h1>
* <p>
* Sometimes you may want to do extra processing right before or after requests.
* {@link #interceptors()} field let you define one or several
* {@link org.springframework.http.client.ClientHttpRequestInterceptor}.
* </p>
* <p>
* An interceptor allow the developer to customize the execution flow of
* requests. It may be useful to handle custom authentication, automatically log
* each requests, and so on.
* </p>
* <blockquote>
*
* <b>Example :</b>
*
* <pre>
* @Rest(converters = MappingJacksonHttpMessageConverter.class, interceptors = HttpBasicAuthenticatorInterceptor.class)
* public interface MyRestClient {
*
* @Get("/events")
* EventList getEvents();
* }
*
* public class HttpBasicAuthenticatorInterceptor implements ClientHttpRequestInterceptor {
*
* @Override
* public ClientHttpResponse intercept(HttpRequest request, byte[] data, ClientHttpRequestExecution execution) throws IOException {
* // do something before sending request
* return execution.execute(request, data);
* }
* }
* </pre>
*
* </blockquote>
*
* <p>
* You can also inject {@link org.androidannotations.annotations.EBean EBean}
* interceptors. Just add the annotated class (not the generated one) to the
* {@link Rest#interceptors() interceptors()} parameter, and the interceptor
* will be added with all of its dependencies.
*
* </p>
*
* <h1>RequestFactory</h1>
* <p>
* You can use your own request factory if you want to customize how requests
* are created. The {@link #requestFactory()} parameter lets you define the
* {@link org.springframework.http.client.ClientHttpRequestFactory
* ClientHttpRequestFactory}.
* </p>
*
* <p>
* You can inject {@link org.androidannotations.annotations.EBean EBean} request
* factories just like as interceptors.
* </p>
* <blockquote>
*
* <b>Example :</b>
*
* <pre>
* @Rest(converters = MappingJacksonHttpMessageConverter.class, <b>requestFactory</b> = MyRequestFactory.class)
* public interface MyRestClient {
*
* @Get("/events")
* EventList getEvents();
* }
*
* public class MyRequestFactory implements ClientHttpRequestFactory {
*
* @Override
* public ClientHttpRequest createRequest(URI uri, HttpMethod httpMethod) throws IOException {
* // create and return the request
* }
* }
* </pre>
*
* </blockquote>
*
* <h1>ResponseErrorHandler</h1>
* <p>
* You can use your own error handler to customize how errors
* are handled. The {@link #responseErrorHandler()} parameter lets you define the
* {@link org.springframework.web.client.ResponseErrorHandler
* ResponseErrorHandler}.
* </p>
*
* <p>
* You can inject an {@link org.androidannotations.annotations.EBean EBean} response errork
* handler just like as a request factory.
* </p>
* <blockquote>
*
* <b>Example :</b>
*
* <pre>
* @Rest(converters = MappingJacksonHttpMessageConverter.class, <b>responseErrorHandler</b> = MyResponseErrorHandler.class)
* public interface MyRestClient {
*
* @Get("/events")
* EventList getEvents();
* }
*
* public class MyResponseErrorHandler implements ResponseErrorHandler {
*
* @Override
* void handleError(ClientHttpResponse response) throws IOException {
* // handles the error in the given response
* }
*
* @Override
* boolean hasError(ClientHttpResponse response) throws IOException {
* // indicates whether the given response has any errors
* return true;
* }
* }
* </pre>
*
* </blockquote>
*
* <h1>Magic methods</h1>
* <p>
* AA will automatically detect and implement some methods in {@link Rest}
* annotated interface. These methods will let you dynamically customize the
* RestClient.
* </p>
* <h2>RootUrl</h2>
* <p>
* We seen earlier that root url can be set via {@link #rootUrl()} annotation
* field, but it only takes a constant. If you want to dynamically inject or
* retrieve the root url, you can add the following code :
* </p>
* <blockquote>
*
* <pre>
* @Rest(converters = MappingJacksonHttpMessageConverter.class)
* public interface MyRestClient {
*
* void setRootUrl(String rootUrl);
*
* String getRootUrl();
* }
* </pre>
*
* </blockquote>
*
* <h2>RestTemplate</h2>
* <p>
* If you want to configure the injected RestTemplate used internally, AA will
* also detect getter and setter for this object.
* </p>
* <blockquote>
*
* <pre>
* @Rest(converters = MappingJacksonHttpMessageConverter.class)
* public interface MyRestClient {
*
* RestTemplate getRestTemplate();
*
* void setRestTemplate(RestTemplate restTemplate);
* }
* </pre>
*
* </blockquote>
*
* <h2>Bundle interfaces</h2>
* <p>
* Since 3.0, we're also providing some bundle interface your RestClient can
* extends of. Each of them provide handled methods subset and let you clean
* your code by using extends composition instead of writing methods.
* </p>
* <p>
* Available bundle interfaces :
* </p>
* <ul>
* <li><b>RestClientRootUrl</b>: provide <code>getRootUrl()</code> and
* <code>setRootUrl()</code></li>
* <li><b>RestClientSupport</b>: provide <code>getRestTemplate()</code> and
* <code>setRestTemplate()</code></li>
* <li><b>RestClientHeaders</b>: provide <code>getHeader()</code>,
* <code>setHeader()</code>, <code>getCookie()</code>, <code>setCookie()</code>,
* <code>setAuthentication()</code> and <code>setHttpBasicAuth()</code></li>
* </ul>
*
*
* @see RestService
* @see org.androidannotations.rest.spring.api.RestClientSupport
* @see org.androidannotations.rest.spring.api.RestClientRootUrl
* @see org.androidannotations.rest.spring.api.RestClientHeaders
*/
@Retention(RetentionPolicy.CLASS)
@Target(ElementType.TYPE)
public @interface Rest {
/**
* The root url of the web service.
*
* @return the root url of the web service
*/
String rootUrl() default "";
/**
* The classes of the converters which should be used to convert received
* data into Java objects.
*
* @return the converter classes
*/
Class<?>[] converters();
/**
* The classes of interceptors which are used to do extra processing before
* or after requests.
*
* @return the interceptor classes
*/
Class<?>[] interceptors() default {};
/**
* The request factory class which is used to create the HTTP requests.
*
* @return the request factory class
*/
Class<?> requestFactory() default Void.class;
/**
* The response error handler class which is used to handle errors.
*
* @return the response error handler class
*/
Class<?> responseErrorHandler() default Void.class;
}