use of org.folio.rest.tools.parser.JsonPathParser in project raml-module-builder by folio-org.
the class Response method mapFrom.
/**
* pull a specific field / section from response1 and populate this response with that section
* @param response1
* @param extractField
* @param intoField
* @param allowNulls
* @return
*/
public Response mapFrom(Response response1, String extractField, String intoField, String nameOfInsert, boolean allowNulls) throws ResponseNullPointer {
if (response1 == null || response1.body == null) {
throw new ResponseNullPointer();
}
if (this.body == null) {
this.body = new JsonObject();
}
JsonPathParser jpp = new JsonPathParser(response1.body);
// get list of paths within the json to join on
List<StringBuilder> sbList = jpp.getAbsolutePaths(extractField);
if (sbList == null) {
// path does not exist in the json, nothing to join on, return response
return this;
}
JsonPathParser result = new JsonPathParser(this.body);
int size = sbList.size();
boolean isArray = false;
if (extractField.contains("[*]")) {
// probably the contains is enough and no need to check size
isArray = true;
}
JsonObject ret = new JsonObject();
for (int i = 0; i < size; i++) {
Object val = jpp.getValueAt(sbList.get(i));
if (val == null && !allowNulls) {
continue;
}
String fixedPath = intoField;
if (isArray) {
fixedPath = fixedPath + "[" + i + "]";
}
result.setValueAt(fixedPath, val, nameOfInsert);
}
return this;
}
use of org.folio.rest.tools.parser.JsonPathParser in project raml-module-builder by folio-org.
the class Response method joinOn.
/**
* join this response with response parameter using the withField field name on the current
* response and the onField field from the response passed in as a parameter (Basically, merge
* entries from the two responses when the values of the withField and onField match.
* Replace the withField in the current response
* with the value found in the insertField (from the Response parameter)
* @param withField
* @param response
* @param onField
* @param extractField - the field to extract from the response to join on. Two options:
* 1. an absolute path - such as a.b.c or a.b.c.d[0] - should be used when one field needs to be
* extracted
* 2. a relative path - such as ../../abc - should be used in cases where the join on is an array
* of results, and we want to extract the specific field for each item in the array to push into the
* response we are joining with.
* @param intoField - the field in the current Response's json to merge into
* @param allowNulls
* @return
* @throws ResponseNullPointer
*/
public Response joinOn(Response response1, String withField, Response response2, String onField, String extractField, String intoField, boolean allowNulls) throws ResponseNullPointer {
if ((this.body == null && response1 == null) || response2 == null || response2.body == null) {
throw new ResponseNullPointer();
}
JsonPathParser output = null;
JsonObject input = null;
if (response1 != null && response1.body != null) {
input = response1.body;
if (this.body == null) {
this.body = new JsonObject();
}
output = new JsonPathParser(this.body);
} else {
input = this.body;
}
JsonPathParser jpp = new JsonPathParser(response2.body);
// get list of paths within the json to join on
List<StringBuilder> sbList = jpp.getAbsolutePaths(onField);
if (sbList == null) {
// path does not exist in the json, nothing to join on, return response
return this;
}
Multimap<Object, ArrayList<Object>> joinTable = ArrayListMultimap.create();
// Map<Object, Object> joinTable = new HashMap<>();
int size = sbList.size();
for (int i = 0; i < size; i++) {
Pairs map = jpp.getValueAndParentPair(sbList.get(i));
if (map != null && map.getRequestedValue() != null) {
ArrayList<Object> a = new ArrayList<>();
a.add(sbList.get(i));
a.add(map.getRootNode());
joinTable.put(map.getRequestedValue(), a);
}
}
jpp = new JsonPathParser(input);
List<StringBuilder> list = jpp.getAbsolutePaths(withField);
int size2 = 0;
if (list != null) {
// if withField path does not exist in json the list will be null
size2 = list.size();
}
for (int i = 0; i < size2; i++) {
// get object for each requested absolute path (withField) needed to compare with the
// join table values
Object valueAtPath = jpp.getValueAt(list.get(i).toString());
// check if the value at the requested path also exists in the join table.
// if so, get the corresponding object from the join table that will replace a value
// in the current json
Collection<ArrayList<Object>> o = joinTable.get(valueAtPath);
if (o != null && o.size() > 0) {
// there is a match between the two jsons, can either be a single match or a match to multiple
// matches
Object toInsert = null;
int arrayPlacement = 0;
// this can be the entire object, or a value found at a path within the object aka insertField
if (o.size() == 1 && extractField != null) {
String tempEField = extractField;
ArrayList<Object> b = o.iterator().next();
if (extractField.contains("../")) {
tempEField = backTrack(b.get(0).toString(), extractField);
}
toInsert = new JsonPathParser((JsonObject) b.get(1)).getValueAt(tempEField);
} else if (o.size() > 1 && extractField != null) {
// more then one of the same value mapped to different objects, create a jsonarray
// with all the values and insert the jsonarray
toInsert = new JsonArray();
Iterator<?> it = o.iterator();
while (it.hasNext()) {
String tempEField = extractField;
ArrayList<Object> b = (ArrayList) it.next();
if (extractField.contains("../")) {
tempEField = backTrack(b.get(0).toString(), extractField);
}
Object object = new JsonPathParser((JsonObject) b.get(1)).getValueAt(tempEField);
if (object != null) {
((JsonArray) toInsert).add(object);
}
}
} else {
toInsert = o.iterator().next();
}
if (!allowNulls && toInsert == null) {
continue;
}
if (intoField != null) {
// get the path in the json to replace with the value from the join table
Object into = null;
String tempIntoField = intoField;
if (output != null) {
Pairs p = output.getValueAndParentPair(list.get(i));
if (p != null) {
// there is an existing value in this jsons path
into = p.getRootNode();
} else {
output.setValueAt(tempIntoField, toInsert);
}
} else {
into = jpp.getValueAndParentPair(list.get(i)).getRootNode();
}
if (intoField.contains("../")) {
tempIntoField = backTrack(list.get(i).toString(), intoField);
}
JsonPathParser jpp2 = new JsonPathParser((JsonObject) into);
Object placeWhereReplacementShouldHappen = jpp2.getValueAt(tempIntoField);
if (placeWhereReplacementShouldHappen instanceof JsonArray) {
((JsonArray) placeWhereReplacementShouldHappen).add(toInsert);
} else {
if (output != null) {
output.setValueAt(tempIntoField, toInsert);
} else {
jpp2.setValueAt(tempIntoField, toInsert);
}
}
} else {
if (output != null) {
// update new json
output.setValueAt(list.get(i).toString(), toInsert);
} else {
// update this.body
jpp.setValueAt(list.get(i).toString(), toInsert);
}
}
} else {
if (allowNulls) {
if (intoField != null) {
String tempIntoField = intoField;
if (intoField.contains("../")) {
tempIntoField = backTrack(list.get(i).toString(), intoField);
}
jpp.setValueAt(tempIntoField, null);
} else {
jpp.setValueAt(list.get(i).toString(), null);
}
}
}
}
if (output != null) {
Response r = new Response();
r.setBody(output.getJsonObject());
return r;
}
return this;
}
Aggregations