use of org.folio.rest.tools.parser.JsonPathParser.Pairs in project raml-module-builder by folio-org.
the class JsonParserTest method check.
@Test
public void check() {
JsonObject j1 = null;
try {
j1 = new JsonObject(IOUtils.toString(JsonPathParser.class.getClassLoader().getResourceAsStream("pathTest.json"), "UTF-8"));
} catch (IOException e) {
e.printStackTrace();
}
JsonPathParser jp = new JsonPathParser(j1);
List<StringBuilder> o = jp.getAbsolutePaths("c.arr[*].a2.'aaa.ccc'");
assertEquals(o.size(), 2);
List<StringBuilder> o2 = jp.getAbsolutePaths("c.arr[*].a2.arr2[*]");
assertEquals(o2.size(), 5);
List<StringBuilder> o3 = jp.getAbsolutePaths("c.arr[*].a2.arr2[*].arr3[*]");
assertEquals(o3.size(), 2);
List<StringBuilder> o4 = jp.getAbsolutePaths("c.arr[*]");
assertEquals(o4.size(), 3);
List<StringBuilder> o5 = jp.getAbsolutePaths("c.arr[0].a2.'aaa.ccc'");
assertEquals("c.arr[0].a2.'aaa.ccc'", o5.get(0).toString());
List<StringBuilder> o6 = jp.getAbsolutePaths("c.a1");
assertEquals(o6.size(), 1);
List<StringBuilder> o7 = jp.getAbsolutePaths("c.arr[*].a2.arr2[*].arr3[*].a32");
assertEquals(o7.size(), 2);
// fix
Pairs p = jp.getValueAndParentPair("c.arr[0].a2.'aaa.ccc'");
assertEquals("aaa.bbb", p.getRequestedValue());
assertTrue(((JsonObject) p.getRootNode()).containsKey("a"));
Pairs p2 = jp.getValueAndParentPair("c.arr[3].a2.arr2[2].arr3[1]");
assertNull(p2);
Pairs p3 = jp.getValueAndParentPair("c.arr[0]");
assertEquals(p3.getRequestedValue(), jp.getValueAt("c.arr[0]"));
assertEquals("2", ((JsonObject) p3.getRootNode()).getString("b"));
assertEquals(new JsonArray("[{\"a32\":\"5\"}, {\"a32\":\"6\"}]").encode().replace(" ", ""), (new JsonArray(((List) jp.getValueAt("c.arr[*].a2.arr2[*].arr3[*]"))).encode().replaceAll(" ", "")));
String v1 = (String) ((List) jp.getValueAt("c.arr[*].a2.'aaa.ccc'")).get(0);
assertEquals("aaa.bbb", v1);
jp.setValueAt("c.arr[0].a2.'aaa.ccc'", "aaa.ccc");
jp.setValueAt("c.arr[2].a2.'aaa.ccc'", "aaa.ddd");
String v2 = (String) ((List) jp.getValueAt("c.arr[*].a2.'aaa.ccc'")).get(0);
assertEquals("aaa.ccc", v2);
String v3 = (String) ((List) jp.getValueAt("c.arr[*].a2.'aaa.ccc'")).get(2);
assertEquals("aaa.ddd", v3);
assertEquals(((List) jp.getValueAt("c.arr[*].a2.arr2[*]")).size(), 5);
jp.setValueAt("c.arr[0].a2.arr2[0]", "yyy");
String v4 = (String) ((List) jp.getValueAt("c.arr[*].a2.arr2[*]")).get(0);
assertEquals("yyy", v4);
// check nulls
assertNull(jp.getValueAt("c.arr[1].a2.'aaa.ccc'"));
// set value of non existent path will create that path
jp.setValueAt("c.arr[1].a2.'aaa.ccc'", "aaa.ddd");
assertEquals("aaa.ddd", jp.getValueAt("c.arr[1].a2.'aaa.ccc'"));
assertEquals("aaa.ccc", jp.getValueAt("c.arr[0].a2.'aaa.ccc'"));
assertTrue((Boolean) jp.getValueAt("boolean"));
assertEquals(99, jp.getValueAt("number"));
assertEquals(2, ((JsonObject) jp.getValueAt("c.arr[0].a2.arr2[2]")).getJsonArray("arr3").size());
jp.setValueAt("c.arr[0].a2", new JsonObject("{\"xqq\":\"xaa\"}"));
assertEquals("{\"xqq\":\"xaa\"}", ((JsonObject) jp.getValueAt("c.arr[0].a2")).encode());
jp.setValueAt("c.arr[*]", new JsonObject());
// schema test
JsonObject j22 = null;
try {
j22 = new JsonObject(IOUtils.toString(JsonPathParser.class.getClassLoader().getResourceAsStream("userdata.json"), "UTF-8"));
} catch (IOException e) {
e.printStackTrace();
}
JsonPathParser jp2 = new JsonPathParser(j22, true);
assertEquals("string", jp2.getValueAt("personal.preferredContact.desc.type"));
assertNull(jp2.getValueAt("personals.preferredContact.desc.type"));
assertNull(jp2.getValueAt("personal.properties.preferredContact.properties.desc.type"));
assertEquals("personal.preferredContact.desc.type", jp2.getAbsolutePaths("personal.preferredContact.desc.type").get(0).toString());
assertEquals("string", jp2.getValueAndParentPair("personal.preferredContact.desc.type").getRequestedValue());
assertNull(jp2.getValueAndParentPair("personal2.preferredContact.desc.type"));
}
use of org.folio.rest.tools.parser.JsonPathParser.Pairs 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