package com.box.boxjavalibv2.responseparsers;

import java.io.InputStream;

import org.apache.commons.io.IOUtils;
import org.apache.commons.lang.StringUtils;

import com.box.boxjavalibv2.dao.BoxGenericServerError;
import com.box.boxjavalibv2.dao.BoxServerError;
import com.box.boxjavalibv2.exceptions.BoxUnexpectedStatus;
import com.box.boxjavalibv2.interfaces.IBoxJSONParser;
import com.box.restclientv2.exceptions.BoxRestException;
import com.box.restclientv2.interfaces.IBoxResponse;
import com.box.restclientv2.responseparsers.DefaultBoxJSONResponseParser;
import com.box.restclientv2.responses.DefaultBoxResponse;

/**
 * Parser to parse {@link com.box.restclientv2.responses.DefaultBoxResponse} into {@link com.box.boxjavalibv2.dao.BoxServerError} objects. It analyse the
 * response JSON String and uses <a href="http://jackson.codehaus.org/">Jackson JSON processor</a> to generate {@link com.box.boxjavalibv2.dao.BoxServerError}
 * objects.
 */
public class ErrorResponseParser extends DefaultBoxJSONResponseParser {

    public ErrorResponseParser(final IBoxJSONParser parser) {
        super(BoxServerError.class, parser);
    }

    @Override
    public Object parse(IBoxResponse response) throws BoxRestException {
        if (!(response instanceof DefaultBoxResponse)) {
            throw new BoxRestException("class mismatch, expected:" + DefaultBoxResponse.class.getName() + ";current:" + response.getClass().getName());
        }

        int statusCode = ((DefaultBoxResponse) response).getHttpResponse().getStatusLine().getStatusCode();
        BoxServerError error = null;
        if (isErrorResponse(statusCode)) {
            error = (BoxServerError) super.parse(response);
        }
        else {
            error = new BoxUnexpectedStatus(statusCode);
        }
        error.setStatus(statusCode);
        return error;
    }

    @SuppressWarnings("unchecked")
    @Override
    protected Object parseInputStream(InputStream in) {
        String errorStr = null;
        try {
            errorStr = IOUtils.toString(in);
            return getParser().parseIntoBoxObject(errorStr, getObjectClass());
        }
        catch (Exception e) {
            BoxGenericServerError genericE = new BoxGenericServerError();
            if (StringUtils.isEmpty(errorStr)) {
                errorStr = e.getMessage();
            }
            genericE.setMessage(errorStr);
            return genericE;
        }
    }

    private boolean isErrorResponse(int statusCode) {
        return statusCode >= 400 && statusCode < 600;
    }
}

@@ -247,32 +247,80 @@
 BoxServerError;%0A
+import com.box.boxjavalibv2.dao.BoxTypedObject;%0A
 import com.box.b
@@ -2102,22 +2102,36 @@
         
-return
+BoxTypedObject obj =
  getPars
@@ -2195,113 +2195,329 @@
     
-%7D%0A
     
-    catch (Exception e) %7B%0A            BoxGenericServerError genericE = new BoxGenericServerError();
+// JSON parser falls back to BoxTypedObject when there is no %22type%22 in error String. In this case, this %22BoxTypedObject%22 does not really make sense%0A            // and should not be used.%0A            if (obj instanceof BoxServerError) %7B%0A                return obj;%0A            %7D%0A        %7D%0A        catch (Exception e) %7B
 %0A   
@@ -2619,24 +2619,101 @@
       %7D%0A    
+    %7D%0A%0A        BoxGenericServerError genericE = new BoxGenericServerError();%0A
         gene
@@ -2743,28 +2743,24 @@
 r);%0A        
-    
 return gener
@@ -2764,26 +2764,16 @@
 nericE;%0A
-        %7D%0A
     %7D%0A%0A 

Fix a bug parsing error responses. Bug was introduced by a change to make json parser more robust. The change was to make parsing of BoxTypedObject fall back to base type if "type" field doesn't exist or is unknown. However caused a json parsing exception swallowed and produced a class cast exception