/* * Copyright 2013 ArcBees 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 com.gwtplatform.dispatch.rest.client.core; import java.util.Set; import javax.inject.Inject; import javax.inject.Provider; import javax.ws.rs.core.HttpHeaders; import com.google.gwt.http.client.Response; import com.gwtplatform.dispatch.rest.client.serialization.Serialization; import com.gwtplatform.dispatch.rest.client.serialization.SerializationException; import com.gwtplatform.dispatch.rest.shared.ContentType; import com.gwtplatform.dispatch.rest.shared.RestAction; import com.gwtplatform.dispatch.shared.ActionException; /** * Default implementation for {@link ResponseDeserializer}. */ public class DefaultResponseDeserializer implements ResponseDeserializer { private final Provider<Set<Serialization>> serializationsProvider; private Set<Serialization> serializations; @Inject protected DefaultResponseDeserializer(Provider<Set<Serialization>> serializationsProvider) { this.serializationsProvider = serializationsProvider; } @Override public <A extends RestAction<R>, R> R deserialize(A action, Response response) throws ActionException { if (isSuccessStatusCode(response)) { return getDeserializedResponse(action, response); } else { throw new ActionException(response.getStatusText()); } } /** * Find a deserializer capable of handling <code>resultType</code> and <code>contentType</code>. * * @param resultType the parameterized type to verify if it can be deserialized. * @param contentType the contentType of the value that requires deserialization. * * @return <code>true</code> if <code>resultType</code> can be deserialized, <code>false</code> otherwise. */ protected Serialization findSerialization(String resultType, ContentType contentType) { for (Serialization serialization : getSerializations()) { if (serialization.canDeserialize(resultType, contentType)) { return serialization; } } return null; } /** * Deserializes the data as an object of the <code>resultClass</code> type using the given * <code>serialization</code> instance. * * @param <R> the type of the object once deserialized. * @param serialization the serialization object to be used. * @param resultClass the parameterized type of the object once deserialized. * @param contentType the contentType of <code>data</code>. * @param data the data to deserialize. @return The deserialized object. */ protected <R> R deserializeValue(Serialization serialization, String resultClass, ContentType contentType, String data) throws ActionException { try { return serialization.deserialize(resultClass, contentType, data); } catch (SerializationException e) { throw new ActionException(e); } } private boolean isSuccessStatusCode(Response response) { int statusCode = response.getStatusCode(); return (statusCode >= 200 && statusCode < 300) || statusCode == 304; } private <R> R getDeserializedResponse(RestAction<R> action, Response response) throws ActionException { String resultClass = action.getResultClass(); if (resultClass != null) { ContentType contentType = ContentType.valueOf(response.getHeader(HttpHeaders.CONTENT_TYPE)); Serialization serialization = findSerialization(resultClass, contentType); if (serialization != null) { return deserializeValue(serialization, resultClass, contentType, response.getText()); } } throw new ActionException("Unable to deserialize response. No serializer found."); } private Set<Serialization> getSerializations() { if (serializations == null) { serializations = serializationsProvider.get(); } return serializations; } }