All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.lindar.wellrested.vo.WellRestedResponse Maven / Gradle / Ivy

There is a newer version: 1.7.3
Show newest version
package com.lindar.wellrested.vo;

import com.fatboyindustrial.gsonjavatime.Converters;
import com.google.gson.GsonBuilder;
import com.google.gson.JsonDeserializer;
import com.google.gson.reflect.TypeToken;
import com.lindar.wellrested.GsonCustomiser;
import com.lindar.wellrested.util.DateDeserializer;
import com.lindar.wellrested.util.type.CollectionWrapperType;
import com.lindar.wellrested.util.type.ResultWrapperType;
import com.lindar.wellrested.xml.WellRestedXMLUtil;
import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.Setter;
import lombok.ToString;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;

import java.io.Serializable;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.Collections;
import java.util.Date;
import java.util.List;
import java.util.Map;

@ToString
@EqualsAndHashCode
@Slf4j
public class WellRestedResponse implements Serializable {
    private static final long serialVersionUID = 51255400364556607L;

    @Getter @Setter
    private String serverResponse = StringUtils.EMPTY;

    @Getter @Setter
    private int statusCode;

    @Getter @Setter
    private String currentURI;
    
    @Setter
    private List dateFormats;

    @Getter @Setter
    private Map responseHeaders;

    private GsonCustomiser gsonCustomiser;

    public WellRestedResponse setDateFormat(String format) {
        this.dateFormats = Collections.singletonList(format);
        return this;
    }


    private XmlResponseMapper fromXml = new XmlResponseMapper();

    /**
     * Allows you to manage XML responses and map them to Java objects
     */
    public XmlResponseMapper fromXml() {
        return this.fromXml;
    }

    public class XmlResponseMapper {
        public  T castTo(Class objClass) {
            return WellRestedXMLUtil.fromStringToObject(serverResponse, objClass);
        }
    }

    private JsonResponseMapper fromJson = new JsonResponseMapper();

    /**
     * Allows you to manage JSON responses and map them to Java objects
     */
    public JsonResponseMapper fromJson() {
        return this.fromJson;
    }

    public class JsonResponseMapper {
        private Class deserializedObjClass;
        private JsonDeserializer deserializer;

        public JsonResponseMapper setDateFormats(List formats) {
            dateFormats = formats;
            return this;
        }

        public  JsonResponseMapper registerDeserializer(Class deserializedObjClass, JsonDeserializer deserializer) {
            this.deserializedObjClass = deserializedObjClass;
            this.deserializer = deserializer;
            return this;
        }

        public JsonResponseMapper gsonCustomiser(GsonCustomiser gsonCustomiser){
            setGsonCustomiser(gsonCustomiser);
            return this;
        }

        /**
         * Maps a json string to a Java object. If no custom date formats are set, the default date format is: yyyy-MM-dd'T'HH:mm:ssz
         */
        public  T castTo(Class objClass) {
            return castTo((Type) objClass);
        }

        public  T castTo(TypeToken typeToken) {
            return castTo((Type) typeToken.getType());
        }

        public  T castTo(Type type) {
            return gsonBuilder().create().fromJson(serverResponse, type);
        }

        public  List castToList(TypeToken> typeToken) {
            GsonBuilder gsonBuilder = gsonBuilder();
            if (deserializedObjClass != null && deserializer != null) {
                gsonBuilder.registerTypeHierarchyAdapter(deserializedObjClass, deserializer);
            }
            return gsonBuilder.create().fromJson(serverResponse, typeToken.getType());
        }

    }


    private ResultResponseMapper fromResult = new ResultResponseMapper();

    /**
     * NOTE: Use this method only if your json response is of type: {@link Result}.
     * Otherwise use {@link WellRestedResponse#fromJson()}
     */
    public ResultResponseMapper fromResult() {
        return this.fromResult;
    }

    public class ResultResponseMapper {
        @Setter
        private Type type;

        public ResultResponseMapper setDateFormats(List formats) {
            dateFormats = formats;
            return this;
        }

        /**
         * This method allows you to set a {@link ParameterizedType} within another ParameterizedType for cases when
         * your Result object contains another object inside (the wrapper) with a collection of the inner type.
         * 
In this case the structure would be something like this: Result->T->List . * If your collections is even deeper than this, you'll have to build your own ParameterizedType */ public ResultResponseMapper registerDeepCollectionType(Class wrapper, Class inner) { this.type = new ResultWrapperType(new CollectionWrapperType(wrapper, inner)); return this; } public Result cast() { this.type = Result.class; return castTo((Type) null); } public Result castTo(TypeToken> typeToken) { return castTo(typeToken.getType()); } public Result castTo(Type type) { try { if (type == null) { type = this.type; } return gsonBuilder().create().fromJson(serverResponse, type); } catch (Exception ex) { log.info("Error casting response to Result | {}", ex); } return ResultBuilder.failedCastingResult(); } } private GsonBuilder gsonBuilder() { GsonBuilder gsonBuilder = Converters.registerAll(new GsonBuilder()); DateDeserializer dateDeserializer; if (dateFormats != null && !dateFormats.isEmpty()) { dateDeserializer = new DateDeserializer(dateFormats); } else { dateDeserializer = new DateDeserializer(); } gsonBuilder.registerTypeAdapter(Date.class, dateDeserializer); if(gsonCustomiser != null){ gsonCustomiser.customise(gsonBuilder); } return gsonBuilder; } private WellRestedResponse setGsonCustomiser(GsonCustomiser gsonCustomiser){ this.gsonCustomiser = gsonCustomiser; return this; } /** * This method verifies that the server response is not blank (to allow casting) and that the status code is lower * than 300; Please note that a response might still be valid even when a server response is blank but in that case * you don't need to cast anymore and you don't need to call this method. When in doubt please write your own * validation method. * * @return */ public boolean isValid() { return StringUtils.isNotBlank(serverResponse) && statusCode < 300; } /** * This method verifies if the underlying server response can be cast to: {@link com.lindar.wellrested.vo.Result} */ public boolean isResult() { if (StringUtils.isNotBlank(serverResponse)) { try { return fromJson.castTo(Result.class) != null; } catch (Exception e) { log.warn("isResult: exception occurred - {}", e); } } return false; } }