package org.springframework.social.flickr.api.impl; import java.io.ByteArrayInputStream; import java.io.IOException; import org.codehaus.jackson.JsonFactory; import org.codehaus.jackson.JsonNode; import org.codehaus.jackson.JsonParseException; import org.codehaus.jackson.JsonParser; import org.codehaus.jackson.JsonToken; import org.codehaus.jackson.io.SerializedString; import org.codehaus.jackson.map.DeserializationConfig; import org.codehaus.jackson.map.DeserializationContext; import org.codehaus.jackson.map.JsonDeserializer; import org.codehaus.jackson.map.JsonMappingException; import org.codehaus.jackson.map.ObjectMapper; import org.codehaus.jackson.type.JavaType; public class FlickrObjectMapper extends ObjectMapper{ protected Object _unwrapAndDeserialize(JsonParser jp, JavaType rootType, DeserializationContext ctxt, JsonDeserializer<Object> deser) throws IOException, JsonParseException, JsonMappingException { ObjectMapper mapper = new ObjectMapper(); mapper.setDeserializationConfig(ctxt.getConfig()); mapper.disable(DeserializationConfig.Feature.UNWRAP_ROOT_VALUE); jp.setCodec(mapper); JsonNode tree = jp.readValueAsTree(); JsonNode statNode = tree.get("stat"); String status = statNode.getTextValue(); if(!"ok".equals(status)){ JsonNode msgNode = tree.get("message"); String errorMsg = msgNode.getTextValue(); JsonNode codeNode = tree.get("code"); String errorCode = codeNode.getTextValue(); //Based on error Code send diffrent type of exceptions. throw new FlickrException(errorMsg); } jp = jp.getCodec().treeAsTokens(tree); jp.nextToken(); SerializedString rootName = _deserializerProvider.findExpectedRootName(ctxt.getConfig(), rootType); if (jp.getCurrentToken() != JsonToken.START_OBJECT) { throw JsonMappingException.from(jp, "Current token not START_OBJECT (needed to unwrap root name '" +rootName+"'), but "+jp.getCurrentToken()); } if (jp.nextToken() != JsonToken.FIELD_NAME) { throw JsonMappingException.from(jp, "Current token not FIELD_NAME (to contain expected root name '" +rootName+"'), but "+jp.getCurrentToken()); } String actualName = jp.getCurrentName(); /*Following is done for response object in case of POST method */ if("stat".equals(actualName)){ return null; } /*This check can removed completely if required if (!rootName.getValue().equalsIgnoreCase(actualName)) { throw JsonMappingException.from(jp, "Root name '"+actualName+"' does not match expected ('"+rootName +"') for type "+rootType); }*/ // ok, then move to value itself.... jp.nextToken(); Object result = deser.deserialize(jp, ctxt); // Ignoring stat field and its value. jp.nextToken(); jp.nextToken(); if (jp.nextToken() != JsonToken.END_OBJECT) { throw JsonMappingException.from(jp, "Current token not END_OBJECT (to match wrapper object with root name '" +rootName+"'), but "+jp.getCurrentToken()); } return result; //return null; } }