package com.sas.unravl.extractors;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.node.ObjectNode;
import com.sas.unravl.ApiCall;
import com.sas.unravl.UnRAVL;
import com.sas.unravl.UnRAVLException;
import com.sas.unravl.annotations.UnRAVLExtractorPlugin;
import com.sas.unravl.generators.Text;
import com.sas.unravl.util.Json;
import org.apache.log4j.Logger;
/**
* An extractor for
*
* <pre>
* { "json" : "varName" }
* { "json" : "@file-name" }
* </pre>
*
* <p>
* In both cases, the JSON body is also bound to the variable
* <code>"responseBody"</code>. The value will be a Jackson
* <code>ObjectNode</code> or <code>ArrayNode</code>.
* <p>
* This extractor also allows an option, <code>"unwrap"</code>:
* </p>
*
* <pre>
* { "json" : "varName", "unwrap" : true }
* { "json" : "@file-name", "unwrap" : true }
* </pre>
* <p>
* If the <code>"unwrap"</code> option is <code>true</code>, the JSON value will
* be "unwrapped". An <code>ObjectNode</code> will be unwrapped into a
* <code>java.util.Map</code>; a <code>ArrayNode</code> will be unwrapped into a
* <code>java.util.List</code>.
*
* @author David.Biesack@sas.com
*/
@UnRAVLExtractorPlugin("json")
public class JsonExtractor extends BaseUnRAVLExtractor {
private static final Logger logger = Logger.getLogger(JsonExtractor.class);
@Override
public void extract(UnRAVL current, ObjectNode extractor, ApiCall call)
throws UnRAVLException {
super.extract(current, extractor, call);
JsonNode target = Json.firstFieldValue(extractor);
boolean unwrap = unwrapOption(extractor);
if (!target.isTextual())
throw new UnRAVLException(
"json binding value must be a var name or a @file-name string");
String to = target.textValue();
JsonNode json = Json.parse(Text.utf8ToString(call.getResponseBody()
.toByteArray()));
Object result = unwrap ? Json.unwrap(json) : json;
current.bind("responseBody", result);
if (to.startsWith(UnRAVL.REDIRECT_PREFIX)) {
String where = to.substring(UnRAVL.REDIRECT_PREFIX.length());
where = getScript().expand(where);
Json.extractToStream(json, where);
if (!where.equals("-"))
logger.info("Wrote JSON to file " + where);
} else {
current.bind(to, result);
}
}
}