/*
 * Copyright (c) 2013-2015 M-Way Solutions GmbH
 *
 * 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.jenkinsci.plugins.relution_publisher.net.responses;

import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;

import org.apache.commons.lang.StringUtils;
import org.apache.http.HttpResponse;


/**
 * Represents a response returned by the Relution server.
 */
public class ApiResponse {

    private final static Gson GSON = new GsonBuilder().setPrettyPrinting().create();

    private HttpResponse      httpResponse;
    private int               statusCode;
    private String            reason;

    private final Integer status;
    private String        message;

    private final JsonObject errors;

    private final int       total;
    private final JsonArray results;

    private transient String s;

    /**
     * Converts the specified JSON formatted string to an instance of the specified class.
     * @param json A JSON formatted string.
     * @return An instance of the specified class.
     */
    public static ApiResponse fromJson(final String json) {
        final JsonParser parser = new JsonParser();
        final JsonElement element = parser.parse(json);
        return new ApiResponse(element.getAsJsonObject());
    }

    /**
     * Initializes a new instance of the {@link ApiResponse} class.
     */
    public ApiResponse() {
        this.status = null;

        this.message = null;
        this.errors = new JsonObject();

        this.total = 0;
        this.results = new JsonArray();
    }

    private ApiResponse(final JsonObject object) {
        this.status = object.get("status").getAsInt();

        this.message = object.get("message").getAsString();
        this.errors = object.get("errors").getAsJsonObject();

        this.total = object.get("total").getAsInt();
        this.results = object.get("results").getAsJsonArray();
    /**
     * Returns the underlying HTTP response.
     * @return The {@link HttpResponse} from which this API response was parsed.
     */
    public HttpResponse getHttpResponse() {
        return this.httpResponse;
    }

    /**
     * Initializes the response from the specified {@link HttpResponse}.
     * @param httpResponse A {@link HttpResponse} used to initialize internal fields.
     */
    public void setHttpResponse(final HttpResponse httpResponse) {
        this.httpResponse = httpResponse;
        this.statusCode = httpResponse.getStatusLine().getStatusCode();
        this.reason = httpResponse.getStatusLine().getReasonPhrase();
    }

    /**
     * @return The HTTP status code returned by the server.
     */
    public int getStatusCode() {
        return this.statusCode;
    }

    /**
     * @return The status returned by the server.
     */
    public int getStatus() {

        if (this.status == null) {
            return this.statusCode;
        }
        return this.status;
    }

    /**
     * @return The message returned by the server.
     */
    public String getMessage() {

        if (StringUtils.isBlank(this.message)) {
            return this.reason;
        }
        return this.message;
    }

    /**
     * Sets the message returned by the server.
     * @param message The message to set.
     */
    public void setMessage(final String message) {
        this.message = message;
    }

    /**
     * @return The {@link Error} returned by the server, or {@code null} if no error occurred.
     */
    public JsonObject getError() {
        return this.errors;
    }

    /**
     * @return The total number of results returned by the server.
     */
    public int getCount() {
        return this.total;
    }

    /**
     * @return The results returned by the server.
     */
    public JsonArray getResults() {
        return this.results;
    }

    /**
     * @return A JSON formatted String that represents this instance.
     */
    public String toJson() {
        return GSON.toJson(this);
    }

    @Override
    public String toString() {

        if (this.s == null) {
            this.s = this.toJson();
        }
        return this.s;
    }
}

@@ -794,22 +794,21 @@
 son.Json
-Elemen
+Objec
 t;%0Aimpor
@@ -821,34 +821,42 @@
 google.gson.
-JsonObject
+annotations.Expose
 ;%0Aimport com
@@ -868,26 +868,42 @@
 le.gson.
-JsonParser
+annotations.SerializedName
 ;%0A%0Aimpor
@@ -1285,16 +1285,58 @@
 eason;%0A%0A
+    @Expose%0A    @SerializedName(%22status%22)%0A
     priv
@@ -1353,23 +1353,71 @@
 Integer 
+    
 status;
+%0A%0A    @Expose%0A    @SerializedName(%22message%22)
 %0A    pri
@@ -1435,16 +1435,20 @@
         
+    
 message;
@@ -1449,16 +1449,58 @@
 ssage;%0A%0A
+    @Expose%0A    @SerializedName(%22errors%22)%0A
     priv
@@ -1520,16 +1520,17 @@
 nObject 
+ 
 errors;%0A
@@ -1526,24 +1526,65 @@
 t  errors;%0A%0A
+    @Expose%0A    @SerializedName(%22total%22)%0A
     private 
@@ -1599,22 +1599,68 @@
 t       
+  
 total;
+%0A%0A    @Expose%0A    @SerializedName(%22results%22)
 %0A    pri
@@ -1680,16 +1680,18 @@
 onArray 
+  
 results;
@@ -1721,16 +1721,17 @@
  String 
+ 
 s;%0A%0A    
@@ -2006,45 +2006,37 @@
 nal 
-JsonParser parser
+Gson gson
  = new 
-JsonPars
+GsonBuild
 er()
-;
 %0A   
@@ -2044,56 +2044,84 @@
     
-final JsonElement element = parser.parse(json
+        .excludeFieldsWithoutExposeAnnotation()%0A                .create(
 );%0A
+%0A
     
@@ -2135,49 +2135,45 @@
 urn 
-new ApiResponse(element.getAsJsonObject()
+gson.fromJson(json, ApiResponse.class
 );%0A 
@@ -2463,354 +2463,8 @@
  %7D%0A%0A
-    private ApiResponse(final JsonObject object) %7B%0A        this.status = object.get(%22status%22).getAsInt();%0A%0A        this.message = object.get(%22message%22).getAsString();%0A        this.errors = object.get(%22errors%22).getAsJsonObject();%0A%0A        this.total = object.get(%22total%22).getAsInt();%0A        this.results = object.get(%22results%22).getAsJsonArray();%0A
     

Use GSON to parse API response for fault tolerance