Skip to content

Commit 88e45d0

Browse files
committed
support wildcard
1 parent 94bf563 commit 88e45d0

7 files changed

Lines changed: 74 additions & 10 deletions

File tree

src/main/java/com/jsoniter/StaticCodeGenerator.java

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,16 +10,16 @@
1010
public class StaticCodeGenerator {
1111
public static void main(String[] args) throws Exception {
1212
String configClassName = args[0];
13+
String configJavaFile = configClassName.replace('.', '/') + ".java";
14+
if (!new File(configJavaFile).exists()) {
15+
throw new JsonException("must execute static code generator in the java source code directory which contains: " + configJavaFile);
16+
}
1317
Class<?> clazz = Class.forName(configClassName);
1418
CodegenConfig config = (CodegenConfig) clazz.newInstance();
1519
JsonIterator.setMode(DecodingMode.DYNAMIC_MODE_AND_MATCH_FIELD_WITH_HASH);
1620
JsonStream.setMode(EncodingMode.DYNAMIC_MODE);
1721
config.setup();
1822
CodegenAccess.staticGenDecoders(config.whatToCodegen());
1923
com.jsoniter.output.CodegenAccess.staticGenEncoders(config.whatToCodegen());
20-
String configJavaFile = configClassName.replace('.', '/') + ".java";
21-
if (!new File(configJavaFile).exists()) {
22-
throw new JsonException("must execute static code generator in the java source code directory which contains: " + configJavaFile);
23-
}
2424
}
2525
}

src/main/java/com/jsoniter/any/Any.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -392,4 +392,11 @@ public static Any wrapAnyList(List<Any> val) {
392392
public static Any wrapAnyMap(Map<String, Any> val) {
393393
return new ObjectAny(val);
394394
}
395+
396+
private final static int wildcardHashCode = Character.valueOf('*').hashCode();
397+
private final static Character wildcard = '*';
398+
399+
protected boolean isWildcard(Object key) {
400+
return wildcardHashCode == key.hashCode() && wildcard.equals(key);
401+
}
395402
}

src/main/java/com/jsoniter/any/ArrayAny.java

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
import com.jsoniter.output.JsonStream;
55

66
import java.io.IOException;
7+
import java.util.ArrayList;
78
import java.util.Iterator;
89
import java.util.List;
910

@@ -61,7 +62,15 @@ public Any get(Object[] keys, int idx) {
6162
if (idx == keys.length) {
6263
return this;
6364
}
64-
return val.get((Integer) keys[idx]).get(keys, idx+1);
65+
Object key = keys[idx];
66+
if (isWildcard(key)) {
67+
ArrayList<Any> result = new ArrayList<Any>();
68+
for (Any element : val) {
69+
result.add(element.get(keys, idx+1));
70+
}
71+
return Any.wrapAnyList(result);
72+
}
73+
return val.get((Integer) key).get(keys, idx+1);
6574
}
6675

6776
@Override

src/main/java/com/jsoniter/any/ArrayLazyAny.java

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ class ArrayLazyAny extends LazyAny {
1515

1616
public ArrayLazyAny(byte[] data, int head, int tail) {
1717
super(data, head, tail);
18+
lastParsedPos = head;
1819
}
1920

2021
@Override
@@ -68,7 +69,16 @@ public Any get(Object[] keys, int idx) {
6869
if (idx == keys.length) {
6970
return this;
7071
}
71-
return fillCache((Integer) keys[idx]).get(keys, idx + 1);
72+
Object key = keys[idx];
73+
if (isWildcard(key)) {
74+
fillCache();
75+
ArrayList<Any> result = new ArrayList<Any>();
76+
for (Any element : cache) {
77+
result.add(element.get(keys, idx+1));
78+
}
79+
return Any.wrapAnyList(result);
80+
}
81+
return fillCache((Integer) key).get(keys, idx + 1);
7282
}
7383

7484
@Override
@@ -120,7 +130,7 @@ private Any fillCache(int target) {
120130
}
121131
int i = cache.size();
122132
if (target < i) {
123-
return cache.get(i);
133+
return cache.get(target);
124134
}
125135
try {
126136
JsonIterator iter = JsonIterator.tlsIter.get();
@@ -136,6 +146,7 @@ private Any fillCache(int target) {
136146
lastParsedPos = CodegenAccess.head(iter);
137147
return element;
138148
}
149+
i = 1;
139150
}
140151
while (CodegenAccess.nextToken(iter) == ',') {
141152
Any element = iter.readAny();

src/main/java/com/jsoniter/any/ObjectAny.java

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
import com.jsoniter.output.JsonStream;
55

66
import java.io.IOException;
7+
import java.util.HashMap;
78
import java.util.Map;
89

910
class ObjectAny extends Any {
@@ -60,11 +61,19 @@ public Any get(Object[] keys, int idx) {
6061
if (idx == keys.length) {
6162
return this;
6263
}
63-
Any child = val.get(keys[idx]);
64+
Object key = keys[idx];
65+
if (isWildcard(key)) {
66+
HashMap<String, Any> result = new HashMap<String, Any>();
67+
for (Map.Entry<String, Any> entry : val.entrySet()) {
68+
result.put(entry.getKey(), entry.getValue().get(keys, idx + 1));
69+
}
70+
return Any.wrapAnyMap(result);
71+
}
72+
Any child = val.get(key);
6473
if (child == null) {
6574
return null;
6675
}
67-
return child.get(keys, idx+1);
76+
return child.get(keys, idx + 1);
6877
}
6978

7079
@Override

src/main/java/com/jsoniter/any/ObjectLazyAny.java

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,16 @@ public Any get(Object[] keys, int idx) {
6767
if (idx == keys.length) {
6868
return this;
6969
}
70-
Any child = fillCache(keys[idx]);
70+
Object key = keys[idx];
71+
if (isWildcard(key)) {
72+
fillCache();
73+
HashMap<String, Any> result = new HashMap<String, Any>();
74+
for (Map.Entry<Object, Any> entry : cache.entrySet()) {
75+
result.put((String) entry.getKey(), entry.getValue().get(keys, idx+1));
76+
}
77+
return Any.wrapAnyMap(result);
78+
}
79+
Any child = fillCache(key);
7180
if (child == null) {
7281
return null;
7382
}

src/test/java/com/jsoniter/TestNested.java

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package com.jsoniter;
22

3+
import com.jsoniter.annotation.JsonIgnore;
34
import com.jsoniter.any.Any;
45
import junit.framework.TestCase;
56
import org.junit.Assert;
@@ -25,4 +26,22 @@ public void test_array_of_objects() throws IOException {
2526
Any any = iter.readAny();
2627
assertEquals("22", any.toString(1, "field2"));
2728
}
29+
30+
public void test_get_all_array_elements_via_any() throws IOException {
31+
Any any = JsonIterator.deserialize(" [ { \"bar\": 1 }, {\"bar\": 3} ]");
32+
Any result = any.get('*', "bar");
33+
assertEquals("[ 1, 3]", result.toString());
34+
any = Any.wrapAnyList(any.asList()); // make it not lazy
35+
result = any.get('*', "bar");
36+
assertEquals("[ 1, 3]", result.toString());
37+
}
38+
39+
public void test_get_all_object_values_via_any() throws IOException {
40+
Any any = JsonIterator.deserialize("{\"field1\":[1,2],\"field2\":[3,4]}");
41+
Any result = any.get('*', 1);
42+
assertEquals("{\"field1\":2,\"field2\":4}", result.toString());
43+
any = Any.wrapAnyMap(any.asMap()); // make it not lazy
44+
result = any.get('*', 1);
45+
assertEquals("{\"field1\":2,\"field2\":4}", result.toString());
46+
}
2847
}

0 commit comments

Comments
 (0)