Skip to content
This repository was archived by the owner on Oct 31, 2024. It is now read-only.

Commit 1bd93b1

Browse files
committed
add jackson-jr implementation
1 parent fb01569 commit 1bd93b1

File tree

4 files changed

+349
-0
lines changed

4 files changed

+349
-0
lines changed

jmespath-jackson-jr/pom.xml

+56
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<!--
3+
~ Copyright 2023 Amazon.com, Inc. or its affiliates.
4+
~ Licensed under the Apache License, Version 2.0 (the
5+
~ "License"); you may not use this file except in compliance
6+
~ with the License. You may obtain a copy of the License at
7+
~ http://www.apache.org/licenses/LICENSE-2.0
8+
~ Unless required by applicable law or agreed to in writing, software
9+
~ distributed under the License is distributed on an "AS IS" BASIS,
10+
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11+
~ See the License for the specific language governing permissions and
12+
~ limitations under the License.
13+
~
14+
-->
15+
16+
<project xmlns="http://maven.apache.org/POM/4.0.0"
17+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
18+
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
19+
<modelVersion>4.0.0</modelVersion>
20+
21+
<artifactId>jmespath-jackson-jr</artifactId>
22+
<name>JMESPath JacksonJr</name>
23+
<description>A JMESPath implementation for Java</description>
24+
25+
<parent>
26+
<groupId>io.burt</groupId>
27+
<artifactId>jmespath</artifactId>
28+
<version>0.5.2-SNAPSHOT</version>
29+
</parent>
30+
31+
<dependencies>
32+
<dependency>
33+
<groupId>${project.groupId}</groupId>
34+
<artifactId>jmespath-core</artifactId>
35+
<version>${project.parent.version}</version>
36+
</dependency>
37+
<dependency>
38+
<groupId>${project.groupId}</groupId>
39+
<artifactId>jmespath-core</artifactId>
40+
<version>${project.parent.version}</version>
41+
<type>test-jar</type>
42+
<scope>test</scope>
43+
</dependency>
44+
<dependency>
45+
<groupId>com.fasterxml.jackson.jr</groupId>
46+
<artifactId>jackson-jr-objects</artifactId>
47+
<version>2.14.2</version>
48+
</dependency>
49+
<dependency>
50+
<groupId>com.fasterxml.jackson.jr</groupId>
51+
<artifactId>jackson-jr-stree</artifactId>
52+
<version>2.14.2</version>
53+
</dependency>
54+
</dependencies>
55+
56+
</project>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,239 @@
1+
/*
2+
* Copyright 2023 Amazon.com, Inc. or its affiliates.
3+
* Licensed under the Apache License, Version 2.0 (the
4+
* "License"); you may not use this file except in compliance
5+
* with the License. You may obtain a copy of the License at
6+
* http://www.apache.org/licenses/LICENSE-2.0
7+
* Unless required by applicable law or agreed to in writing, software
8+
* distributed under the License is distributed on an "AS IS" BASIS,
9+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
10+
* See the License for the specific language governing permissions and
11+
* limitations under the License.
12+
*
13+
*/
14+
15+
package io.burt.jmespath.jacksonjr;
16+
17+
import com.fasterxml.jackson.core.JsonToken;
18+
import com.fasterxml.jackson.core.TreeNode;
19+
import com.fasterxml.jackson.jr.ob.JSON;
20+
import com.fasterxml.jackson.jr.stree.JacksonJrsTreeCodec;
21+
import com.fasterxml.jackson.jr.stree.JrsArray;
22+
import com.fasterxml.jackson.jr.stree.JrsBoolean;
23+
import com.fasterxml.jackson.jr.stree.JrsNull;
24+
import com.fasterxml.jackson.jr.stree.JrsNumber;
25+
import com.fasterxml.jackson.jr.stree.JrsObject;
26+
import com.fasterxml.jackson.jr.stree.JrsString;
27+
import com.fasterxml.jackson.jr.stree.JrsValue;
28+
import io.burt.jmespath.BaseRuntime;
29+
import io.burt.jmespath.JmesPathType;
30+
import io.burt.jmespath.RuntimeConfiguration;
31+
import java.io.IOException;
32+
import java.util.AbstractList;
33+
import java.util.ArrayList;
34+
import java.util.Collection;
35+
import java.util.Collections;
36+
import java.util.HashMap;
37+
import java.util.Iterator;
38+
import java.util.List;
39+
import java.util.Map;
40+
41+
public class JacksonJrRuntime extends BaseRuntime<TreeNode> {
42+
private final JSON json;
43+
public JacksonJrRuntime() {
44+
this(RuntimeConfiguration.defaultConfiguration());
45+
}
46+
47+
public JacksonJrRuntime(RuntimeConfiguration configuration) {
48+
this(configuration, JSON.builder()
49+
.treeCodec(new JacksonJrsTreeCodec())
50+
.build());
51+
}
52+
public JacksonJrRuntime(RuntimeConfiguration configuration, JSON json) {
53+
super(configuration);
54+
this.json = json;
55+
}
56+
57+
@Override
58+
public TreeNode parseString(String str) {
59+
try {
60+
return json.treeFrom(str);
61+
} catch (IOException e) {
62+
throw new IllegalStateException(e);
63+
}
64+
}
65+
66+
private static class JrsArrayListWrapper extends AbstractList<TreeNode> {
67+
private final JrsArray array;
68+
69+
JrsArrayListWrapper(JrsArray array) {
70+
this.array = array;
71+
}
72+
73+
@Override
74+
public TreeNode get(int index) {
75+
return array.get(index);
76+
}
77+
78+
@Override
79+
public int size() {
80+
return array.size();
81+
}
82+
}
83+
84+
@Override
85+
public List<TreeNode> toList(TreeNode value) {
86+
if (value == null) {
87+
return Collections.emptyList();
88+
}
89+
if (value.isArray()) {
90+
return new JrsArrayListWrapper((JrsArray) value);
91+
} else if (value.isObject()) {
92+
JrsObject object = (JrsObject) value;
93+
List<TreeNode> list = new ArrayList<>(object.size());
94+
Iterator<Map.Entry<String, JrsValue>> iterator = object.fields();
95+
96+
while (iterator.hasNext()) {
97+
Map.Entry<String, TreeNode> entry = (Map.Entry) iterator.next();
98+
list.add(entry.getValue());
99+
}
100+
return list;
101+
} else {
102+
return Collections.emptyList();
103+
}
104+
}
105+
106+
@Override
107+
public String toString(TreeNode value) {
108+
if (value.asToken().equals(JsonToken.VALUE_STRING)) {
109+
return ((JrsString) value).asText();
110+
} else {
111+
try {
112+
return json.asString(value);
113+
} catch (IOException e) {
114+
return "";
115+
}
116+
}
117+
}
118+
119+
@Override
120+
public Number toNumber(TreeNode value) {
121+
if (value.isValueNode() && ((JrsValue) value).isNumber()) {
122+
JrsNumber number = (JrsNumber) value;
123+
return number.getValue();
124+
} else return null;
125+
}
126+
127+
@Override
128+
public boolean isTruthy(TreeNode value) {
129+
// false, null, empty lists, empty objects, empty strings.
130+
if (value.isContainerNode()) {
131+
return value.size() > 0;
132+
} else if (value.isValueNode()) {
133+
if (value.asToken().equals(JsonToken.VALUE_STRING)) {
134+
return !((JrsString) value).asText().isEmpty();
135+
} else return !value.asToken().equals(JsonToken.VALUE_FALSE) &&
136+
!value.asToken().equals(JsonToken.VALUE_NULL);
137+
} else {
138+
return !value.isMissingNode();
139+
}
140+
}
141+
142+
@Override
143+
public JmesPathType typeOf(TreeNode value) {
144+
switch (value.asToken()) {
145+
case START_ARRAY:
146+
case END_ARRAY:
147+
return JmesPathType.ARRAY;
148+
case VALUE_EMBEDDED_OBJECT:
149+
case START_OBJECT:
150+
case END_OBJECT:
151+
return JmesPathType.OBJECT;
152+
case VALUE_STRING:
153+
return JmesPathType.STRING;
154+
case VALUE_NUMBER_INT:
155+
case VALUE_NUMBER_FLOAT:
156+
return JmesPathType.NUMBER;
157+
case VALUE_TRUE:
158+
case VALUE_FALSE:
159+
return JmesPathType.BOOLEAN;
160+
case VALUE_NULL:
161+
return JmesPathType.NULL;
162+
case NOT_AVAILABLE:
163+
default:
164+
throw new IllegalStateException(String.format("Unknown node type encountered: %s", value.asToken()));
165+
}
166+
}
167+
168+
@Override
169+
public TreeNode getProperty(TreeNode value, TreeNode name) {
170+
if (value == null || value.asToken().equals(JsonToken.VALUE_NULL)) {
171+
return JrsNull.instance();
172+
} else {
173+
TreeNode node = value.get(((JrsString) name).asText());
174+
return node != null ? node : createNull();
175+
}
176+
}
177+
178+
@Override
179+
public Collection<TreeNode> getPropertyNames(TreeNode value) {
180+
if (value != null && value.isObject()) {
181+
List<TreeNode> names = new ArrayList<>(value.size());
182+
Iterator<String> fieldNames = value.fieldNames();
183+
while (fieldNames.hasNext()) {
184+
names.add(createString(fieldNames.next()));
185+
}
186+
return names;
187+
} else {
188+
return Collections.emptyList();
189+
}
190+
}
191+
192+
@Override
193+
public TreeNode createNull() {
194+
return JrsNull.instance();
195+
}
196+
197+
@Override
198+
public TreeNode createArray(Collection<TreeNode> elements) {
199+
List<JrsValue> values = new ArrayList<>();
200+
for (TreeNode node: elements) {
201+
if (node == null) {
202+
values.add(JrsNull.instance());
203+
} else {
204+
values.add((JrsValue) node);
205+
}
206+
}
207+
return new JrsArray(values);
208+
209+
}
210+
211+
@Override
212+
public TreeNode createString(String str) {
213+
return new JrsString(str);
214+
}
215+
216+
@Override
217+
public TreeNode createBoolean(boolean b) {
218+
return b ? JrsBoolean.TRUE : JrsBoolean.FALSE;
219+
}
220+
221+
@Override
222+
public TreeNode createObject(Map<TreeNode, TreeNode> obj) {
223+
Map<String, JrsValue> values = new HashMap<>();
224+
for (Map.Entry<TreeNode, TreeNode> entry : obj.entrySet()) {
225+
values.put(((JrsString)entry.getKey()).asText(), (JrsValue) entry.getValue());
226+
}
227+
return new JrsObject(values);
228+
}
229+
230+
@Override
231+
public TreeNode createNumber(double n) {
232+
return new JrsNumber(n);
233+
}
234+
235+
@Override
236+
public TreeNode createNumber(long n) {
237+
return new JrsNumber(n);
238+
}
239+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
/*
2+
* Copyright 2023 Amazon.com, Inc. or its affiliates.
3+
* Licensed under the Apache License, Version 2.0 (the
4+
* "License"); you may not use this file except in compliance
5+
* with the License. You may obtain a copy of the License at
6+
* http://www.apache.org/licenses/LICENSE-2.0
7+
* Unless required by applicable law or agreed to in writing, software
8+
* distributed under the License is distributed on an "AS IS" BASIS,
9+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
10+
* See the License for the specific language governing permissions and
11+
* limitations under the License.
12+
*
13+
*/
14+
15+
package io.burt.jmespath.jacksonjr;
16+
17+
import com.fasterxml.jackson.core.TreeNode;
18+
import io.burt.jmespath.Adapter;
19+
import io.burt.jmespath.JmesPathComplianceTest;
20+
21+
public class JacksonJrComplianceTest extends JmesPathComplianceTest<TreeNode> {
22+
private Adapter<TreeNode> runtime = new JacksonJrRuntime();
23+
24+
@Override
25+
protected Adapter<TreeNode> runtime() { return runtime; }
26+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
/*
2+
* Copyright 2023 Amazon.com, Inc. or its affiliates.
3+
* Licensed under the Apache License, Version 2.0 (the
4+
* "License"); you may not use this file except in compliance
5+
* with the License. You may obtain a copy of the License at
6+
* http://www.apache.org/licenses/LICENSE-2.0
7+
* Unless required by applicable law or agreed to in writing, software
8+
* distributed under the License is distributed on an "AS IS" BASIS,
9+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
10+
* See the License for the specific language governing permissions and
11+
* limitations under the License.
12+
*
13+
*/
14+
15+
package io.burt.jmespath.jacksonjr;
16+
17+
18+
import com.fasterxml.jackson.core.TreeNode;
19+
import io.burt.jmespath.Adapter;
20+
import io.burt.jmespath.JmesPathRuntimeTest;
21+
import io.burt.jmespath.RuntimeConfiguration;
22+
23+
public class JacksonJrTest extends JmesPathRuntimeTest<TreeNode> {
24+
@Override
25+
protected Adapter<TreeNode> createRuntime(RuntimeConfiguration configuration) {
26+
return new JacksonJrRuntime(configuration);
27+
}
28+
}

0 commit comments

Comments
 (0)