octomix / josson

A query language for JSON and a template engine to generate text output.
Apache License 2.0
32 stars 8 forks source link

Custom function #17

Open boryspiela opened 3 months ago

boryspiela commented 3 months ago

Is it possible to define somehow custom function? I have scenario that I want to process JSON list of objects and I want to assign UUID to every object. When I'm creating transformation and run it each item gets the same UUID. It's reasonable because UUID.randomUuid().toString() is ran once to generate transformation and given value is applied to every processed element. The only solution that I have now is to retrieve items count upfront then create standard Java's loop or something to iterate over path by passing index and generate separate transformations for each item.

IntStream.range(0, Josson.getValueNode("elements.size()").asInt())
        .mapToObj(index -> "elements[" + index + "].map(id:UUID.randomUUID().toString(),name:name)")
        .toArray(String[]::new)

I haven't performed any benchmarks but it seems to generate performance overhead.

octomix commented 3 months ago

Yes, I'm planning to add custom function feature to Josson query in version 1.5.

octomix commented 2 months ago

@boryspiela Version 1.5.0 has been released. You can define your own custom functions to manipulate a node in a Josson query. Customer function name must starts with "$" and ends with "()".

To do what you want, the syntax is very simple.

Josson josson = Josson.fromJsonString(
        "[" +
        "    {\"id\": 2, \"name\": \"Apple\"}," +
        "    {\"id\": 3, \"name\": \"Orange\"}," +
        "    {\"id\": 5, \"name\": \"Banana\"}" +
        "]"
    )
    .customFunction(
        "$randomUuid()",
        (node) -> TextNode.valueOf(UUID.randomUUID().toString())
    );
JsonNode node = josson.getNode("field(uuid:$randomUuid())");
System.out.println(node.toPrettyString());

Output

[ {
  "id" : 2,
  "name" : "Apple",
  "uuid" : "06016eed-1547-42a9-9c10-4ccdf9a50593"
}, {
  "id" : 3,
  "name" : "Orange",
  "uuid" : "b0bb7565-9322-41b4-a055-f6043c6ff899"
}, {
  "id" : 5,
  "name" : "Banana",
  "uuid" : "f0a3b93f-cacb-4064-8432-0cc83796fa8e"
} ]