Skip to content

Commit

Permalink
Merge branch 'release-0.0.9'
Browse files Browse the repository at this point in the history
  • Loading branch information
eiiches committed Jul 17, 2018
2 parents a359dc9 + 0fe09f6 commit 60e9281
Show file tree
Hide file tree
Showing 22 changed files with 129 additions and 38 deletions.
5 changes: 3 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ Just add jackson-jq in your pom.xml.
<dependency>
<groupId>net.thisptr</groupId>
<artifactId>jackson-jq</artifactId>
<version>0.0.8</version>
<version>0.0.9</version>
</dependency>
</dependencies>
```
Expand Down Expand Up @@ -104,6 +104,7 @@ Here is a *current* status of differences between jackson-jq and the jq. If you
- [Modules](https://stedolan.github.io/jq/manual/#Modules)
- [Streaming](https://stedolan.github.io/jq/manual/#Streaming)
- [I/O](https://stedolan.github.io/jq/manual/#IO)
- `{$foo}` syntax, a syntactic sugar for `{foo:$foo}` (#24)

- Missing functions in jackson-jq
- Datetime functions: `fromdate/0`, `mktime/0`, `gmtime/0`
Expand Down Expand Up @@ -141,7 +142,7 @@ Using jackson-jq-extra module
<dependency>
<groupId>net.thisptr</groupId>
<artifactId>jackson-jq-extra</artifactId>
<version>0.0.8</version>
<version>0.0.9</version>
</dependency>
</dependencies>
```
Expand Down
4 changes: 2 additions & 2 deletions jackson-jq-cli/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,14 @@
<parent>
<groupId>net.thisptr</groupId>
<artifactId>jackson-jq-parent</artifactId>
<version>0.0.8</version>
<version>0.0.9</version>
</parent>

<dependencies>
<dependency>
<groupId>net.thisptr</groupId>
<artifactId>jackson-jq-extra</artifactId>
<version>0.0.8</version>
<version>0.0.9</version>
</dependency>
<dependency>
<groupId>commons-cli</groupId>
Expand Down
4 changes: 2 additions & 2 deletions jackson-jq-extra/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,14 @@
<parent>
<groupId>net.thisptr</groupId>
<artifactId>jackson-jq-parent</artifactId>
<version>0.0.8</version>
<version>0.0.9</version>
</parent>

<dependencies>
<dependency>
<groupId>net.thisptr</groupId>
<artifactId>jackson-jq</artifactId>
<version>0.0.8</version>
<version>0.0.9</version>
</dependency>
</dependencies>
</project>
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,9 @@
public class UriParseFunctionTest {
@Test
public void test() throws JsonQueryException {
final Scope scope = Scope.newEmptyScope();
scope.loadFunctions(Scope.class.getClassLoader());
// check this does not throw NPE
new UriParseFunction().apply(new Scope(), Collections.<JsonQuery> emptyList(), new TextNode("http://google.com"));
new UriParseFunction().apply(scope, Collections.<JsonQuery> emptyList(), new TextNode("http://google.com"));
}
}
2 changes: 1 addition & 1 deletion jackson-jq/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
<parent>
<groupId>net.thisptr</groupId>
<artifactId>jackson-jq-parent</artifactId>
<version>0.0.8</version>
<version>0.0.9</version>
</parent>

<dependencies>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,16 +6,17 @@
import net.thisptr.jackson.jq.exception.JsonQueryException;
import net.thisptr.jackson.jq.internal.IsolatedScopeQuery;
import net.thisptr.jackson.jq.internal.javacc.JsonQueryParser;
import net.thisptr.jackson.jq.internal.javacc.ParseException;
import net.thisptr.jackson.jq.internal.javacc.TokenMgrError;

import com.fasterxml.jackson.databind.JsonNode;

public abstract class JsonQuery {
@Deprecated
private static Scope defaultScope = new Scope();

public abstract List<JsonNode> apply(final Scope scope, final JsonNode in) throws JsonQueryException;

@Deprecated
public List<JsonNode> apply(final JsonNode in) throws JsonQueryException {
return apply(defaultScope, in);
}
Expand All @@ -27,14 +28,15 @@ public List<JsonNode> apply(final Scope scope, final List<JsonNode> in) throws J
return out;
}

@Deprecated
public List<JsonNode> apply(final List<JsonNode> in) throws JsonQueryException {
return apply(defaultScope, in);
}

public static JsonQuery compile(final String path) throws JsonQueryException {
try {
return new IsolatedScopeQuery(JsonQueryParser.compile(path));
} catch (final TokenMgrError | ParseException e) {
} catch (final TokenMgrError | Exception e) {
throw new JsonQueryException(e);
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,10 @@
public class JsonQueryUtils {
private JsonQueryUtils() {}

@Deprecated
private static Scope defaultScope = new Scope();

@Deprecated
public static <T> List<T> apply(final JsonQuery jq, final Object in, final Class<T> resultType) throws IOException {
return apply(defaultScope, jq, in, resultType);
}
Expand All @@ -21,6 +23,7 @@ public static <T> List<T> apply(final Scope scope, final JsonQuery jq, final Obj
return map(scope.getObjectMapper(), jq.apply(scope, (JsonNode) scope.getObjectMapper().valueToTree(in)), resultType);
}

@Deprecated
public static <T> List<T> apply(final JsonQuery jq, final Object in, final TypeReference<T> resultType) throws IOException {
return apply(defaultScope, jq, in, resultType);
}
Expand Down
16 changes: 13 additions & 3 deletions jackson-jq/src/main/java/net/thisptr/jackson/jq/Scope.java
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.MappingIterator;
import com.fasterxml.jackson.databind.ObjectMapper;

import net.thisptr.jackson.jq.exception.JsonQueryException;
import net.thisptr.jackson.jq.internal.BuiltinFunction;
import net.thisptr.jackson.jq.internal.JsonQueryFunction;
Expand Down Expand Up @@ -75,11 +76,11 @@ private Map<String, String> debugFunctions() {
private ObjectMapper mapper = DEFAULT_MAPPER;

/**
* Use {@link #Scope(Scope) Scope(null)} instead and explicitly
* Use {@link Scope#newEmptyScope()} instead and explicitly
* call {@link #loadFunctions(ClassLoader)} with the appropriate
* {@link ClassLoader} for your application. E.g.:
* <pre>
* final Scope scope = new Scope(null);
* final Scope scope = Scope.newEmptyScope();
* scope.loadFunctions(Thread.currentThread().getContextClassLoader());
* </pre>
*/
Expand All @@ -88,10 +89,19 @@ public Scope() {
this(RootScopeHolder.INSTANCE);
}

@Deprecated
public Scope(final Scope parentScope) {
this.parentScope = parentScope;
}

public static Scope newEmptyScope() {
return new Scope(null);
}

public static Scope newChildScope(final Scope scope) {
return new Scope(scope);
}

public void addFunction(final String name, final int n, final Function q) {
functions.put(name + "/" + n, q);
}
Expand Down Expand Up @@ -208,7 +218,7 @@ private void loadMacros(final ClassLoader classLoader, final String path) {
final List<JqJson> configs = loadConfig(classLoader, path);
for (final JqJson jqJson : configs) {
for (final JqJson.JqFuncDef def : jqJson.functions)
addFunction(def.name, def.args.size(), new JsonQueryFunction(def.name, def.args, JsonQuery.compile(def.body)));
addFunction(def.name, def.args.size(), new JsonQueryFunction(def.name, def.args, JsonQuery.compile(def.body), this));
}
} catch (final IOException e) {
throw new RuntimeException("Failed to load macros", e);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ public FixedScopeQuery(final Scope scope, final JsonQuery query) {
}

@Override
public List<JsonNode> apply(final Scope _, final JsonNode in) throws JsonQueryException {
public List<JsonNode> apply(final Scope unused, final JsonNode in) throws JsonQueryException {
return query.apply(scope, in);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ public IsolatedScopeQuery(final JsonQuery q) {

@Override
public List<JsonNode> apply(Scope scope, JsonNode in) throws JsonQueryException {
final Scope isolatedScope = new Scope(scope);
final Scope isolatedScope = Scope.newChildScope(scope);
return q.apply(isolatedScope, in);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,15 +25,11 @@ public JsonQueryFunction(final String name, final List<String> params, final Jso
this.closure = closure;
}

public JsonQueryFunction(final String name, final List<String> params, final JsonQuery body) {
this(name, params, body, Scope.rootScope());
}

@Override
public List<JsonNode> apply(final Scope scope, final List<JsonQuery> args, final JsonNode in) throws JsonQueryException {
Preconditions.checkArgumentCount(name, args, params.size());

final Scope fnScope = new Scope(closure);
final Scope fnScope = Scope.newChildScope(closure);
fnScope.addFunction(name, params.size(), this);

final List<JsonNode> out = new ArrayList<>();
Expand All @@ -53,7 +49,7 @@ private void applyRecursive(final List<JsonNode> out, final Scope fnScope, final
applyRecursive(out, fnScope, scope, args, in, i + 1);
}
} else {
fnScope.addFunction(param, 0, new JsonQueryFunction(param, Collections.<String> emptyList(), new FixedScopeQuery(scope, args.get(i))));
fnScope.addFunction(param, 0, new JsonQueryFunction(param, Collections.<String> emptyList(), new FixedScopeQuery(scope, args.get(i)), fnScope));
applyRecursive(out, fnScope, scope, args, in, i + 1);
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
package net.thisptr.jackson.jq.internal.functions;

import java.util.ArrayList;
import java.util.List;

import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.node.TextNode;

import net.thisptr.jackson.jq.Function;
import net.thisptr.jackson.jq.JsonQuery;
import net.thisptr.jackson.jq.Scope;
import net.thisptr.jackson.jq.exception.JsonQueryException;
import net.thisptr.jackson.jq.exception.JsonQueryTypeException;
import net.thisptr.jackson.jq.internal.BuiltinFunction;

@BuiltinFunction("join/1")
public class JoinFunction implements Function {
@Override
public List<JsonNode> apply(final Scope scope, final List<JsonQuery> args, final JsonNode in) throws JsonQueryException {
final List<JsonNode> out = new ArrayList<>();
for (final JsonNode sep : args.get(0).apply(scope, in)) {

JsonNode isep = null;
final StringBuilder builder = new StringBuilder();
for (final JsonNode item : in) {
if (isep != null) {
if (isep.isTextual()) {
builder.append(isep.asText());
} else if (isep.isNull()) {
// append nothing
} else {
throw new JsonQueryTypeException(new TextNode(builder.toString()), isep, "cannot be added");
}
}

if (item.isTextual()) {
builder.append(item.asText());
} else if (item.isNull()) {
// append nothing
} else if (item.isNumber() || item.isBoolean()) {
// https://github.com/stedolan/jq/commit/e17ccf229723d776c0d49341665256b855c70bda
// https://github.com/stedolan/jq/issues/930
builder.append(item.toString());
} else {
throw new JsonQueryTypeException(new TextNode(builder.toString()), item, "cannot be added");
}

isep = sep;
}
out.add(new TextNode(builder.toString()));
}
return out;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ public List<JsonNode> apply(final Scope scope, final JsonNode in) throws JsonQue
// Wrap in array to allow mutation inside lambda
final JsonNode[] accumulators = new JsonNode[] { accumulator };

final Scope childScope = new Scope(scope);
final Scope childScope = Scope.newChildScope(scope);
for (final JsonNode item : iterExpr.apply(scope, in)) {

final Stack<Pair<String, JsonNode>> stack = new Stack<>();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ private static void applyRecursive(final Scope scope, final JsonNode in, final L
final PatternMatcher matcher = head._2;

final Scope scope2 = matcher != null
? new Scope(scope)
? Scope.newChildScope(scope)
: scope;

for (final JsonNode o : q.apply(scope, in)) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ public List<JsonNode> apply(final Scope scope, final JsonNode in) throws JsonQue

try {

final Scope childScope = new Scope(scope);
final Scope childScope = Scope.newChildScope(scope);
for (final JsonNode item : iterExpr.apply(scope, in)) {
final Stack<Pair<String, JsonNode>> stack = new Stack<>();
matcher.match(scope, item, (final List<Pair<String, JsonNode>> vars) -> {
Expand Down
15 changes: 13 additions & 2 deletions jackson-jq/src/main/javacc/json-query.jj
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,18 @@ TOKEN: {
}

TOKEN: { <SEMICOLON: ";"> }
TOKEN: { <DOT: "."> }

// We have to be careful about spaces after ".". jq-1.4 or newer does not allow spaces between "." and <identifier> in field accessors.
// For example, '. foo' is an error while '.foo' is not. This distinction is important to parse "if . then . else empty end".
// IDENTIFIER_AFTER_DOT and OTHERWISE_AFTER_DOT should not be re-ordered. The order matters.
TOKEN: { <DOT: "."> : STATE_DOT }
<STATE_DOT> TOKEN: {
<IDENTIFIER_AFTER_DOT: <IDENTIFIER>> : DEFAULT
}
<STATE_DOT> MORE: {
<OTHERWISE_AFTER_DOT: ""> : DEFAULT
}

TOKEN: { <RECURSION: ".."> }

TOKEN: { <OPEN_BRACKET: "["> }
Expand Down Expand Up @@ -784,7 +795,7 @@ JsonQuery IdentifierFieldAccessor(JsonQuery obj):
}
{
<DOT>
identifier = <IDENTIFIER>
identifier = <IDENTIFIER_AFTER_DOT>
(
<QUESTION>
{ permissive = true; }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ net.thisptr.jackson.jq.internal.functions.IndicesFunction
net.thisptr.jackson.jq.internal.functions.InfiniteFunction
net.thisptr.jackson.jq.internal.functions.IsInfiniteFunction
net.thisptr.jackson.jq.internal.functions.IsNanFunction
net.thisptr.jackson.jq.internal.functions.JoinFunction
net.thisptr.jackson.jq.internal.functions.KeysFunction
net.thisptr.jackson.jq.internal.functions.LengthFunction
net.thisptr.jackson.jq.internal.functions.LTrimStrFunction
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,6 @@
{"name": "flatten", "args": [], "body": "_flatten(-1)"},
{"name": "flatten", "args": ["$x"], "body": "if $x < 0 then error(\"flatten depth must not be negative\") else _flatten($x) end"},
{"name": "_flatten", "args": ["$x"], "body": "reduce .[] as $i ([]; if $i | type == \"array\" and $x != 0 then . + ($i | _flatten($x-1)) else . + [$i] end)"},
{"name": "join", "args": ["$x"], "body": "reduce .[] as $i (null; (if .==null then \"\" else .+$x end) + ($i | if type==\"boolean\" or type==\"number\" then tostring else .//\"\" end)) // \"\""},
{"name": "match", "args": ["re", "mode"], "body": "_match_impl(re; mode; false)|.[]"},
{"name": "match", "args": ["$val"], "body": "($val|type) as $vt | if $vt == \"string\" then match($val; null) elif $vt == \"array\" and ($val | length) > 1 then match($val[0]; $val[1]) elif $vt == \"array\" and ($val | length) > 0 then match($val[0]; null) else error( $vt + \" not a string or array\") end"},
{"name": "test", "args": ["re", "mode"], "body": "_match_impl(re; mode; true)"},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@

import net.thisptr.jackson.jq.JsonQuery;
import net.thisptr.jackson.jq.Scope;
import net.thisptr.jackson.jq.internal.JsonQueryFunction;

import org.junit.Test;

Expand All @@ -19,11 +18,13 @@
public class JsonQueryFunctionTest {
@Test
public void test() throws JsonProcessingException, IOException {
final Scope scope = new Scope();
final ObjectMapper mapper = new ObjectMapper();

scope.addFunction("inc", 1, new JsonQueryFunction("inc", Arrays.asList("x"), JsonQuery.compile("x + 1")));
scope.addFunction("fib", 1, new JsonQueryFunction("fib", Arrays.asList("x"), JsonQuery.compile("if x == 0 then 0 elif x == 1 then 1 else fib(x-1) + fib(x-2) end")));
final Scope scope = Scope.newEmptyScope();
scope.loadFunctions(Scope.class.getClassLoader());

scope.addFunction("inc", 1, new JsonQueryFunction("inc", Arrays.asList("x"), JsonQuery.compile("x + 1"), scope));
scope.addFunction("fib", 1, new JsonQueryFunction("fib", Arrays.asList("x"), JsonQuery.compile("if x == 0 then 0 elif x == 1 then 1 else fib(x-1) + fib(x-2) end"), scope));
scope.addFunction("fib", 0, new JsonQueryFunction("fib", Arrays.<String> asList(), JsonQuery.compile("fib(.)"), scope));

assertEquals(Arrays.asList(mapper.readTree("2")), JsonQuery.compile("inc(1)").apply(scope, NullNode.getInstance()));
Expand Down
Loading

0 comments on commit 60e9281

Please sign in to comment.