Search in sources :

Example 1 with Pairs

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"));
}
Also used : JsonArray(io.vertx.core.json.JsonArray) JsonObject(io.vertx.core.json.JsonObject) JsonPathParser(org.folio.rest.tools.parser.JsonPathParser) List(java.util.List) IOException(java.io.IOException) Pairs(org.folio.rest.tools.parser.JsonPathParser.Pairs) Test(org.junit.Test)

Example 2 with Pairs

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;
}
Also used : ResponseNullPointer(org.folio.rest.tools.client.exceptions.ResponseNullPointer) ArrayList(java.util.ArrayList) JsonPathParser(org.folio.rest.tools.parser.JsonPathParser) JsonObject(io.vertx.core.json.JsonObject) Pairs(org.folio.rest.tools.parser.JsonPathParser.Pairs) JsonArray(io.vertx.core.json.JsonArray) Iterator(java.util.Iterator) JsonObject(io.vertx.core.json.JsonObject)

Aggregations

JsonArray (io.vertx.core.json.JsonArray)2 JsonObject (io.vertx.core.json.JsonObject)2 JsonPathParser (org.folio.rest.tools.parser.JsonPathParser)2 Pairs (org.folio.rest.tools.parser.JsonPathParser.Pairs)2 IOException (java.io.IOException)1 ArrayList (java.util.ArrayList)1 Iterator (java.util.Iterator)1 List (java.util.List)1 ResponseNullPointer (org.folio.rest.tools.client.exceptions.ResponseNullPointer)1 Test (org.junit.Test)1