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

com.afrigis.services.impl.AbstractResponse Maven / Gradle / Ivy

There is a newer version: 3.0.2
Show newest version
package com.afrigis.services.impl;

import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.nio.charset.Charset;

import org.apache.commons.codec.binary.StringUtils;
import org.apache.commons.io.IOUtils;
import org.apache.http.HttpStatus;
import org.json.JSONObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.afrigis.services.Response;
import com.afrigis.services.exceptions.AfriGISServicesException;
import com.afrigis.services.internal.saas.api2.impl.ParsedErrorData;
import com.google.gson.Gson;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;

/**
 * 

* Abstract implementation for {@link Response}. *

* * @author hendrikc * */ public abstract class AbstractResponse implements Response { private static final int OK_200 = 200; private static final Charset UTF8 = Charset.forName("UTF-8"); private byte[] rawData; private int httpStatusCode; private String errMsg; private ParsedErrorData error; private int timesCalled; @Override public byte[] getByteArray() { return rawData != null ? rawData.clone() : null; } /** * * @return the raw data array direct (NOT a copy) */ protected byte[] getByteArrayInternal() { return rawData; } /** *

* Essentially returns TRUE if we received any suspect http status code. *

*

* Note that the SaaS server, at time of writing, does not seem to honour * HTTP status codes for response. For example, it will happily return 200 * while authentication failed. SO just be aware this method might require * some more intelligence or something. *

* * @return true if this is an error response */ public boolean isError() { boolean ret = false; switch (httpStatusCode) { case HttpStatus.SC_ACCEPTED: case HttpStatus.SC_OK: case HttpStatus.SC_CREATED: case 0: ret = false; break; default: ret = true; break; } // Actual HTTP status code is not accurate reflection of response error // status return ret | error != null; } @Override public void consume(InputStream fin, int realHttpStatusCode) { this.httpStatusCode = realHttpStatusCode; final ByteArrayOutputStream fout = new ByteArrayOutputStream(); try { IOUtils.copy(fin, fout); IOUtils.closeQuietly(fout); final String rawString = fout.toString(UTF8.name()); rawData = fout.toByteArray(); error = checkForErrorCondition(rawString); log().trace("Received from server:\n" + rawString); log().trace("Result: {}", realHttpStatusCode); } catch (Exception e) { realHttpStatusCode = HttpStatus.SC_INTERNAL_SERVER_ERROR; errMsg = e.getMessage(); log().error( "Unexpected exception caught while consuming server response", e); } } /** *

* Complets the parsing of the received response. *

* * @param input * the input as received from server. */ protected abstract void completeBuild(byte[] input); @Override public void completeBuild() { completeBuild(rawData); } /** *

* Attempts to deserialize the received server response. *

* * @param * a class that implements {@link Response} * @param input * a json string received from server side services * @param type * the type of the {@link Response} implementation * @return the deserialized object */ public static T build(String input, Class type) { final ParsedErrorData error = checkForErrorCondition(input); if (error != null) { throw new AfriGISServicesException(error); } else { final Gson gson = new Gson(); final JsonParser parser = new JsonParser(); try { final JsonObject jsonObject = (JsonObject) parser.parse(input); return gson.fromJson(jsonObject, type); } catch (Exception e) { LoggerFactory.getLogger(type) .error("Error encountered in build", e); return null; } } } private static ParsedErrorData checkForErrorCondition(String rawString) { JSONObject parsed = null; try { parsed = new JSONObject(rawString); } catch (Exception e) { LoggerFactory.getLogger(AbstractResponse.class).warn( "Failed to parse response as JSON - this is not expected. The received content is\n{}\n", rawString, e); } try { if (parsed != null) { int httpStatusCode = 0; String errMsg = ""; ParsedErrorData error; if (parsed.has("statusCode") && parsed.getInt("statusCode") != 200) { httpStatusCode = parsed.getInt("statusCode"); errMsg = parsed.optString("message","No Message Available"); } if (httpStatusCode != OK_200 && httpStatusCode != 0) { error = new ParsedErrorData(); error.setMessage(errMsg); error.setSource(parsed.has("source") ? parsed.getString("source") : "Unknown"); error.setStatusCode(httpStatusCode); return error; } } } catch (Exception e) { LoggerFactory.getLogger(AbstractResponse.class).warn( "Treating the response as JSON failed, assuming there is much wrong", e); return new ParsedErrorData(); } return null; } /** *

* Retrieves error message if available. *

* * @return the error message if available, otherwise empty string ( * "") */ public String getErrorMessage() { return errMsg; } /** *

* Extracts the the HTTP status code if possible. *

* * @return the HTTP status code if possible, otherwise returns 0 (zero) */ public int getHttpStatusCode() { return this.httpStatusCode; } @Override public ParsedErrorData getError() { return error; } @Override public void setError(ParsedErrorData receivedErr) { this.error = receivedErr; } @Override public void setTimesCalled(int timesCalledIn) { this.timesCalled = timesCalledIn; } @Override public int getTimesCalled() { return timesCalled; } /** *

* Give you the response as received from the server, unmodified. *

*

* Note, however, we construct the string using the raw byte array received * from the server, with UTF-8 encoding. This MIGHT screw up if the server * is not actually talking UTF-8 *

* * @return the response received from the server as a string, UTF-8 encoded. * @see String#String(byte[], Charset) * @see StringUtils#newStringUtf8(byte[]) */ @Override public String toString() { return StringUtils .newStringUtf8(rawData != null ? rawData : new byte[0]); } /** * * @return {@link Logger} instance */ protected Logger log() { return LoggerFactory.getLogger(getClass()); } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy