X Tutup
Skip to content
This repository was archived by the owner on Feb 26, 2023. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,47 @@
* </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}.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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>
* &#064;Rest(converters = MappingJacksonHttpMessageConverter.class, <b>responseErrorHandler</b> = MyResponseErrorHandler.class)
* public interface MyRestClient {
*
* &#064;Get(&quot;/events&quot;)
* EventList getEvents();
* }
*
* public class MyResponseErrorHandler implements ResponseErrorHandler {
*
* &#064;Override
* void handleError(ClientHttpResponse response) throws IOException {
* // handles the error in the given response
* }
*
* &#064;Override
* boolean hasError(ClientHttpResponse response) throws IOException {
* // indicates whether the given response has any errors
* return true;
* }
* }
* </pre>
*
* </blockquote>
*
* <h1>Magic methods</h1>
* <p>
Expand Down Expand Up @@ -274,4 +315,11 @@
* @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;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
/**
* Copyright (C) 2010-2015 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.test;

import java.io.IOException;

import org.springframework.http.client.ClientHttpResponse;
import org.springframework.web.client.ResponseErrorHandler;

public class MyResponseErrorHandler implements ResponseErrorHandler {

static boolean instanceCreated = false;

public MyResponseErrorHandler() {
instanceCreated = true;
}

@Override
public boolean hasError(ClientHttpResponse clientHttpResponse) throws IOException {
return false;
}

@Override
public void handleError(ClientHttpResponse clientHttpResponse) throws IOException {

}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
/**
* Copyright (C) 2010-2015 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.test;

import java.io.IOException;

import org.androidannotations.annotations.EBean;
import org.springframework.http.client.ClientHttpResponse;
import org.springframework.web.client.ResponseErrorHandler;

@EBean(scope = EBean.Scope.Singleton)
public class MyResponseErrorHandlerBean implements ResponseErrorHandler {

@Override
public boolean hasError(ClientHttpResponse clientHttpResponse) throws IOException {
return false;
}

@Override
public void handleError(ClientHttpResponse clientHttpResponse) throws IOException {

}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
/**
* Copyright (C) 2010-2015 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.test;

import org.androidannotations.rest.spring.annotations.Rest;
import org.androidannotations.rest.spring.api.RestClientSupport;
import org.springframework.http.converter.json.MappingJacksonHttpMessageConverter;

@Rest(converters = { MappingJacksonHttpMessageConverter.class }, responseErrorHandler = MyResponseErrorHandler.class)
public interface RestWithSimpleClassResponseErrorHandler extends RestClientSupport {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
/**
* Copyright (C) 2010-2015 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.test;

import org.androidannotations.rest.spring.annotations.Rest;
import org.androidannotations.rest.spring.api.RestClientSupport;
import org.springframework.http.converter.json.MappingJacksonHttpMessageConverter;

@Rest(converters = { MappingJacksonHttpMessageConverter.class }, responseErrorHandler = MyResponseErrorHandlerBean.class)
public interface RestWithSingletonBeanResponseErrorHandler extends RestClientSupport {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
/**
* Copyright (C) 2010-2015 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.test;

import static org.fest.assertions.api.Assertions.assertThat;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.Robolectric;
import org.robolectric.RobolectricTestRunner;
import org.springframework.web.client.ResponseErrorHandler;

@RunWith(RobolectricTestRunner.class)
public class RestResponseErrorHandlerTest {

@Test
public void testSameAsSingletonBeanResponseErrorHandler() {
RestWithSingletonBeanResponseErrorHandler restClient = new RestWithSingletonBeanResponseErrorHandler_(Robolectric.application);
ResponseErrorHandler errorHandler = restClient.getRestTemplate().getErrorHandler();
MyResponseErrorHandlerBean errorHandlerBean = MyResponseErrorHandlerBean_.getInstance_(Robolectric.application);

assertThat(errorHandler).isSameAs(errorHandlerBean);
}

@Test
public void testInstanceCreatedFromNonBeanClassAsResponseErrorHandler() {
new RestWithSimpleClassResponseErrorHandler_(Robolectric.application);

assertThat(MyResponseErrorHandler.instanceCreated).isTrue();
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,8 @@ public void validate(Element element, ElementValidation validation) {
restSpringValidatorHelper.validateInterceptors(element, validation);

restSpringValidatorHelper.validateRequestFactory(element, validation);

restSpringValidatorHelper.validateResponseErrorHandler(element, validation);
}

@Override
Expand All @@ -86,6 +88,7 @@ public void process(Element element, RestHolder holder) {
setConverters(element, holder);
setInterceptors(element, holder);
setRequestFactory(element, holder);
setResponseErrorHandler(element, holder);
}

private void setRootUrl(Element element, RestHolder holder) {
Expand Down Expand Up @@ -128,4 +131,12 @@ private void setRequestFactory(Element element, RestHolder holder) {
holder.getInit().body().add(invoke(holder.getRestTemplateField(), "setRequestFactory").arg(requestFactory));
}
}

private void setResponseErrorHandler(Element element, RestHolder holder) {
DeclaredType responseErrorHandler = annotationHelper.extractAnnotationClassParameter(element, getTarget(), "responseErrorHandler");
if (responseErrorHandler != null) {
JInvocation errorHandler = codeModelHelper.newBeanOrEBean(responseErrorHandler, holder.getInitContextParam());
holder.getInit().body().add(invoke(holder.getRestTemplateField(), "setErrorHandler").arg(errorHandler));
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ public final class RestSpringClasses {
public static final String HTTP_BASIC_AUTHENTICATION = "org.springframework.http.HttpBasicAuthentication";
public static final String REST_CLIENT_EXCEPTION = "org.springframework.web.client.RestClientException";
public static final String NESTED_RUNTIME_EXCEPTION = "org.springframework.core.NestedRuntimeException";
public static final String RESPONSE_ERROR_HANDLER = "org.springframework.web.client.ResponseErrorHandler";

private RestSpringClasses() {

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -302,36 +302,44 @@ public void validateInterceptors(Element element, ElementValidation valid) {
}
}

public void validateRequestFactory(Element element, ElementValidation valid) {
TypeMirror clientHttpRequestFactoryType = annotationHelper.typeElementFromQualifiedName(CLIENT_HTTP_REQUEST_FACTORY).asType();
DeclaredType requestFactory = annotationHelper.extractAnnotationClassParameter(element, annotationHelper.getTarget(), "requestFactory");
if (requestFactory != null) {
if (annotationHelper.isSubtype(requestFactory, clientHttpRequestFactoryType)) {
Element requestFactoryElement = requestFactory.asElement();
if (requestFactoryElement.getKind().isClass()) {
if (!annotationHelper.isAbstract(requestFactoryElement)) {
if (requestFactoryElement.getAnnotation(EBean.class) != null) {
public void validateRestSimpleParameter(Element element, String requiredClass, String parameterName, ElementValidation validation) {
TypeMirror requiredType = annotationHelper.typeElementFromQualifiedName(requiredClass).asType();
DeclaredType paramterType = annotationHelper.extractAnnotationClassParameter(element, annotationHelper.getTarget(), parameterName);
if (paramterType != null) {
if (annotationHelper.isSubtype(paramterType, requiredType)) {
Element parameterElement = paramterType.asElement();
if (parameterElement.getKind().isClass()) {
if (!annotationHelper.isAbstract(parameterElement)) {
if (parameterElement.getAnnotation(EBean.class) != null) {
return;
}
List<ExecutableElement> constructors = ElementFilter.constructorsIn(requestFactoryElement.getEnclosedElements());
List<ExecutableElement> constructors = ElementFilter.constructorsIn(parameterElement.getEnclosedElements());
for (ExecutableElement constructor : constructors) {
if (annotationHelper.isPublic(constructor) && constructor.getParameters().isEmpty()) {
return;
}
}
valid.addError("The requestFactory class must have a public no argument constructor or must be annotated with @EBean");
validation.addError(element, "The " + parameterName + " class must have a public no argument constructor or must be annotated with @EBean");
} else {
valid.addError("The requestFactory class must not be abstract");
validation.addError(element, "The " + parameterName + " class must not be abstract");
}
} else {
valid.addError("The requestFactory class must be a class");
validation.addError(element, "The " + parameterName + " class must be a class");
}
} else {
valid.addError("The requestFactory class must be a subtype of " + CLIENT_HTTP_REQUEST_FACTORY);
validation.addError(element, "The " + parameterName + " class must be a subtype of " + requiredClass);
}
}
}

public void validateRequestFactory(Element element, ElementValidation validation) {
validateRestSimpleParameter(element, CLIENT_HTTP_REQUEST_FACTORY, "requestFactory", validation);
}

public void validateResponseErrorHandler(Element element, ElementValidation validation) {
validateRestSimpleParameter(element, RestSpringClasses.RESPONSE_ERROR_HANDLER, "responseErrorHandler", validation);
}

public void throwsOnlyRestClientException(ExecutableElement element, ElementValidation valid) {
List<? extends TypeMirror> thrownTypes = element.getThrownTypes();
if (thrownTypes.size() > 0) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
/**
* Copyright (C) 2010-2015 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;

import org.springframework.web.client.ResponseErrorHandler;

public abstract class AbstractResponseErrorHandler implements ResponseErrorHandler {

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
/**
* Copyright (C) 2010-2015 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;

import org.androidannotations.rest.spring.annotations.Rest;
import org.springframework.http.converter.json.MappingJacksonHttpMessageConverter;

@Rest(converters = { MappingJacksonHttpMessageConverter.class }, responseErrorHandler = AbstractResponseErrorHandler.class)
public interface ClientWithAbstractResponseErrorHandler {

}
Loading
X Tutup