Java tutorial
package com.lonepulse.zombielink.response; /* * #%L * ZombieLink * %% * Copyright (C) 2013 - 2014 Lonepulse * %% * 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. * #L% */ import static com.lonepulse.zombielink.util.Components.isDetached; import static com.lonepulse.zombielink.util.Is.async; import static com.lonepulse.zombielink.util.Is.status; import static com.lonepulse.zombielink.util.Is.successful; import java.lang.reflect.Method; import org.apache.http.HttpEntity; import org.apache.http.HttpResponse; import org.apache.http.util.EntityUtils; import com.lonepulse.zombielink.annotation.Deserialize; import com.lonepulse.zombielink.annotation.Entity.ContentType; import com.lonepulse.zombielink.proxy.InvocationContext; /** * <p>This {@link AbstractResponseProcessor} retrieves the {@link HttpEntity} of an {@link HttpResponse} * and deserializes its content using the defined deserializer. Deserializers are defined using * @{@link Deserialize} either at the endpoint level or at the request level. All endpoint request * declarations which define a return type should be associated with a deserializer. Custom deserializers * may be used by extending {@link AbstractDeserializer} and defining its type at {@link Deserialize#type()}.</p> * * @version 1.1.0 * <br><br> * @since 1.3.0 * <br><br> * @author <a href="http://sahan.me">Lahiru Sahan Jayasinghe</a> */ class EntityProcessor extends AbstractResponseProcessor { /** * <p>Accepts the {@link InvocationContext} along with the {@link HttpResponse} and retrieves the * {@link HttpEntity} form the response. This is then converted to an instance of the required request * return type by consulting the @{@link Deserialize} metadata on the endpoint definition.</p> * * <p>If the desired return type is {@link HttpResponse} or {@link HttpEntity} the response or entity * is simply returned without any further processing.</p> * * <p><b>Note</b> that this processor returns {@code null} for successful responses with the status * codes {@code 205} or {@code 205}.</p> * * @param context * the {@link InvocationContext} which is used to discover deserializer metadata * <br><br> * @param response * the {@link HttpResponse} whose response content is deserialized to the desired output type * <br><br> * @return the deserialized response content which conforms to the expected type * <br><br> * @throws ResponseProcessorException * if deserializer instantiation or execution failed for the response entity * <br><br> * @since 1.3.0 */ @Override protected Object process(InvocationContext context, HttpResponse response, Object content) { if (response.getEntity() == null) { return content; } HttpEntity entity = response.getEntity(); Method request = context.getRequest(); Class<?> responseType = request.getReturnType(); try { if (successful(response) && !status(response, 204, 205)) { //omit successful status codes without response content if (HttpResponse.class.isAssignableFrom(responseType)) { return response; } if (HttpEntity.class.isAssignableFrom(responseType)) { return response.getEntity(); } boolean responseExpected = !(responseType.equals(void.class) || responseType.equals(Void.class)); boolean handleAsync = async(context); if (handleAsync || responseExpected) { Class<?> endpoint = context.getEndpoint(); AbstractDeserializer<?> deserializer = null; Deserialize metadata = (metadata = request.getAnnotation(Deserialize.class)) == null ? endpoint.getAnnotation(Deserialize.class) : metadata; if (metadata != null & !isDetached(context, Deserialize.class)) { deserializer = (metadata.value() == ContentType.UNDEFINED) ? Deserializers.resolve(metadata.type()) : Deserializers.resolve(metadata.value()); } else if (handleAsync || CharSequence.class.isAssignableFrom(responseType)) { deserializer = Deserializers.resolve(ContentType.PLAIN); } else { throw new DeserializerUndefinedException(endpoint, request); } return deserializer.run(context, response); } } } catch (Exception e) { throw (e instanceof ResponseProcessorException) ? (ResponseProcessorException) e : new ResponseProcessorException(getClass(), context, e); } finally { if (!(HttpResponse.class.isAssignableFrom(responseType) || HttpEntity.class.isAssignableFrom(responseType))) { EntityUtils.consumeQuietly(entity); } } return content; } }