embulk-filter-column 0.5.4 → 0.6.0.pre1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 0cad32bb6df05ff04fb0501b8b893812d999969e
4
- data.tar.gz: 7c0047d6f7dc5542195abd36a63e50aebdaa405a
3
+ metadata.gz: 8ca161d763f10dc37da758c3bac6d0384a3b4edf
4
+ data.tar.gz: dfe8251c7268898b6ba42c4aa0da2298b2242ba7
5
5
  SHA512:
6
- metadata.gz: 1da990ff7ca9e14bbb7e385998309a979ef8376b3c25d8a117296ea121c82a91bf7cca8ee18439cf3b895b83a54901e37bcb6696ae618d4ee1c71755c1b92fc2
7
- data.tar.gz: dbb3eb97dc117998562791b05ff846078be14cc365f754312e575ad8d0a576fe6575c3c471c6d55cd7fa8884146191cf56faa7e3b0f6a519c8f14d855ab23158
6
+ metadata.gz: c03b1816ca0d300c3b9260dea666d3a361ce9413e685e4ac419923ad27ca925428031969888c7a9d8f25cd511ae127acb987194b761b608044319fee96653ea8
7
+ data.tar.gz: 37d963fc19b1c78028ce043810b3c88badba92b8a72d116e2b30e208dcacdd85a88d2d55a6379cfd9fffff7d234fbd50b306c40d9a3adc74316e7cc522b295bb
data/.travis.yml CHANGED
@@ -4,4 +4,4 @@ jdk:
4
4
  - oraclejdk7
5
5
  - oraclejdk8
6
6
  script:
7
- - ./gradlew test
7
+ - travis_retry ./gradlew test
data/CHANGELOG.md CHANGED
@@ -1,3 +1,9 @@
1
+ # 0.6.0 (2016-10-01)
2
+
3
+ Enhancements:
4
+
5
+ * Support bracket notation in json path (thanks to @kysnm)
6
+
1
7
  # 0.5.4 (2016-08-05)
2
8
 
3
9
  Enhancements:
data/README.md CHANGED
@@ -117,6 +117,7 @@ For type: json column, you can specify [JSONPath](http://goessner.net/articles/J
117
117
  - {name: $.payload.key1}
118
118
  - {name: "$.payload.array[0]"}
119
119
  - {name: "$.payload.array[*]"}
120
+ - {name: $['payload']['key1.key2']}
120
121
  ```
121
122
 
122
123
  EXAMPLE:
data/build.gradle CHANGED
@@ -15,13 +15,14 @@ configurations {
15
15
  provided
16
16
  }
17
17
 
18
- version = "0.5.4"
18
+ version = "0.6.0.pre1"
19
19
  sourceCompatibility = 1.7
20
20
  targetCompatibility = 1.7
21
21
 
22
22
  dependencies {
23
23
  compile "org.embulk:embulk-core:0.8.+"
24
24
  provided "org.embulk:embulk-core:0.8.+"
25
+ compile 'com.dena.analytics:JsonPathCompiler:0.0.6'
25
26
 
26
27
  testCompile "junit:junit:4.+"
27
28
  testCompile "org.embulk:embulk-core:0.8.+:tests"
@@ -0,0 +1,40 @@
1
+ in:
2
+ type: file
3
+ path_prefix: example/example.csv
4
+ parser:
5
+ type: csv
6
+ charset: UTF-8
7
+ newline: CRLF
8
+ null_string: 'NULL'
9
+ skip_header_lines: 1
10
+ comment_line_marker: '#'
11
+ columns:
12
+ - {name: time, type: timestamp, format: "%Y-%m-%d"}
13
+ - {name: id, type: long}
14
+ - {name: name, type: string}
15
+ - {name: score, type: double}
16
+ - {name: json, type: json}
17
+ filters:
18
+ - type: column
19
+ add_columns:
20
+ - {name: "$['json']['array.a']", type: json, default: "[{\"a\":\"a0\"},{\"a\":\"a1\"}]"}
21
+ - {name: "$['json']['array_b']", type: json, default: "[{\"b\":\"b\"},{\"b\":\"b\"}]"}
22
+ - type: column
23
+ columns:
24
+ - {name: time, default: "2015-07-13", format: "%Y-%m-%d"}
25
+ - {name: name, default: "foo"}
26
+ - {name: foo, default: 1, type: long}
27
+ - {name: id}
28
+ - {name: copy_score, src: score}
29
+ - {name: json, default: "{\"foo\":\"FOO\",\"array.a\":[{\"a\":\"default0\"},{\"a\":\"default1\"}],\"array_b\":[{\"b\":\"default\"},{\"b\":\"default\"}]}"}
30
+ - {name: "$['json']['foo']"}
31
+ - {name: "$['json']['copy_foo']", src: "$['json']['foo']"}
32
+ - {name: "$['json']['drop_foo']", src: "$['json']['foo']"}
33
+ - {name: "$['json']['array_a']", src: "$['json']['array.a']"}
34
+ - {name: "$['json']['array_a'][0]"}
35
+ - {name: "$['json']['array_b']"}
36
+ - type: column
37
+ drop_columns:
38
+ - {name: "$['json']['drop_foo']"}
39
+ out:
40
+ type: stdout
@@ -0,0 +1,4 @@
1
+ json
2
+ {"phone']Num\"]ber":"foo","bar":"bar","foo\\']\"]foo":"baz"}
3
+ {"phone']Num\"]ber":"foo2","bar":"bar2","foo\\']\"]foo":"baz2"}
4
+ NULL
@@ -0,0 +1,22 @@
1
+ in:
2
+ type: file
3
+ path_prefix: example/edgecase.tsv
4
+ parser:
5
+ type: csv
6
+ delimiter: \t
7
+ charset: UTF-8
8
+ newline: CRLF
9
+ null_string: 'NULL'
10
+ skip_header_lines: 1
11
+ comment_line_marker: '#'
12
+ columns:
13
+ - {name: json, type: json}
14
+ filters:
15
+ - type: column
16
+ columns:
17
+ - {name: json, default: "{\"phone']Num\\\"]ber\":\"FOO\"}"}
18
+ - {name: "$.json[\"phone']Num\\\"]ber\"]"}
19
+ - {name: $.json.copy_foo, src: "$.json[\"phone']Num\\\"]ber\"]"}
20
+ - {name: "$.json['foo\\']\"]foo']"}
21
+ out:
22
+ type: stdout
@@ -27,6 +27,8 @@ import org.slf4j.Logger;
27
27
 
28
28
  import java.util.List;
29
29
 
30
+ import com.dena.analytics.jsonpathcompiler.expressions.path.PathCompiler;
31
+
30
32
  public class ColumnFilterPlugin implements FilterPlugin
31
33
  {
32
34
  private static final Logger logger = Exec.getLogger(ColumnFilterPlugin.class);
@@ -117,7 +119,7 @@ public class ColumnFilterPlugin implements FilterPlugin
117
119
  boolean matched = false;
118
120
  for (ColumnConfig dropColumn : dropColumns) {
119
121
  // skip json path notation to build outputSchema
120
- if (dropColumn.getName().startsWith("$.")) {
122
+ if (PathCompiler.isProbablyJsonPath(dropColumn.getName())) {
121
123
  continue;
122
124
  }
123
125
  if (dropColumn.getName().equals(name)) {
@@ -134,10 +136,10 @@ public class ColumnFilterPlugin implements FilterPlugin
134
136
  else if (columns.size() > 0) {
135
137
  for (ColumnConfig column : columns) {
136
138
  // skip json path notation to build output schema
137
- if (column.getName().startsWith("$.")) {
139
+ if (PathCompiler.isProbablyJsonPath(column.getName())) {
138
140
  continue;
139
141
  }
140
- if (column.getSrc().isPresent() && column.getSrc().get().startsWith("$.")) {
142
+ if (column.getSrc().isPresent() && PathCompiler.isProbablyJsonPath(column.getSrc().get())) {
141
143
  continue;
142
144
  }
143
145
 
@@ -178,10 +180,10 @@ public class ColumnFilterPlugin implements FilterPlugin
178
180
  if (addColumns.size() > 0) {
179
181
  for (ColumnConfig column : addColumns) {
180
182
  // skip json path notation to build output schema
181
- if (column.getName().startsWith("$.")) {
183
+ if (PathCompiler.isProbablyJsonPath(column.getName())) {
182
184
  continue;
183
185
  }
184
- if (column.getSrc().isPresent() && column.getSrc().get().startsWith("$.")) {
186
+ if (column.getSrc().isPresent() && PathCompiler.isProbablyJsonPath(column.getSrc().get())) {
185
187
  continue;
186
188
  }
187
189
 
@@ -1,5 +1,6 @@
1
1
  package org.embulk.filter.column;
2
2
 
3
+ import com.dena.analytics.jsonpathcompiler.expressions.Utils;
3
4
  import com.google.common.base.Throwables;
4
5
 
5
6
  import org.embulk.filter.column.ColumnFilterPlugin.ColumnConfig;
@@ -244,13 +245,13 @@ public class ColumnVisitorImpl implements ColumnVisitor
244
245
  pageBuilder.setNull(outputColumn);
245
246
  }
246
247
  else {
247
- String jsonPath = new StringBuilder("$.").append(outputColumn.getName()).toString();
248
+ String jsonPath = new StringBuilder("$['").append(Utils.escape(outputColumn.getName(), true)).append("']").toString();
248
249
  pageBuilder.setJson(outputColumn, jsonVisitor.visit(jsonPath, defaultValue));
249
250
  }
250
251
  }
251
252
  else {
252
253
  Value value = pageReader.getJson(inputColumn);
253
- String jsonPath = new StringBuilder("$.").append(outputColumn.getName()).toString();
254
+ String jsonPath = new StringBuilder("$['").append(Utils.escape(outputColumn.getName(), true)).append("']").toString();
254
255
  pageBuilder.setJson(outputColumn, jsonVisitor.visit(jsonPath, value));
255
256
  }
256
257
  }
@@ -1,5 +1,12 @@
1
1
  package org.embulk.filter.column;
2
2
 
3
+ import com.dena.analytics.jsonpathcompiler.expressions.Path;
4
+ import com.dena.analytics.jsonpathcompiler.expressions.path.ArrayIndexOperation;
5
+ import com.dena.analytics.jsonpathcompiler.expressions.path.ArrayPathToken;
6
+ import com.dena.analytics.jsonpathcompiler.expressions.path.PathCompiler;
7
+ import com.dena.analytics.jsonpathcompiler.expressions.path.PathToken;
8
+ import com.dena.analytics.jsonpathcompiler.expressions.path.RootPathToken;
9
+ import com.dena.analytics.jsonpathcompiler.expressions.path.PropertyPathToken;
3
10
  import org.embulk.config.ConfigException;
4
11
  import org.embulk.spi.type.Type;
5
12
  import org.msgpack.value.StringValue;
@@ -15,17 +22,15 @@ public class JsonColumn
15
22
 
16
23
  private StringValue pathValue = null;
17
24
  private String parentPath = null;
18
- private String baseName = null;
19
- private Long baseIndex = null;
25
+ private Long tailIndex = null;
20
26
  private StringValue parentPathValue = null;
21
- private StringValue baseNameValue = null;
27
+ private Value tailNameValue = null;
22
28
 
23
29
  private StringValue srcValue = null;
24
30
  private String srcParentPath = null;
25
- private String srcBaseName = null;
26
- private Long srcBaseIndex = null;
31
+ private Long srcTailIndex = null;
27
32
  private StringValue srcParentPathValue = null;
28
- private StringValue srcBaseNameValue = null;
33
+ private Value srcTailNameValue = null;
29
34
 
30
35
  public JsonColumn(String path, Type type)
31
36
  {
@@ -39,33 +44,67 @@ public class JsonColumn
39
44
 
40
45
  public JsonColumn(String path, Type type, Value defaultValue, String src)
41
46
  {
42
- this.path = path;
47
+ Path compiledPath = PathCompiler.compile(path);
48
+ Path compiledSrc = src == null ? compiledPath : PathCompiler.compile(src);
49
+ RootPathToken compiledRoot = (RootPathToken) compiledPath.getRoot();
50
+ RootPathToken compiledSrcRoot = (RootPathToken) compiledSrc.getRoot();
51
+ this.path = compiledPath.toString();
43
52
  this.type = type;
44
53
  this.defaultValue = (defaultValue == null ? ValueFactory.newNil() : defaultValue);
45
- this.src = (src == null ? path : src);
54
+ this.src = compiledSrc.toString();
46
55
 
47
56
  this.pathValue = ValueFactory.newString(path);
48
- this.parentPath = parentPath(path);
49
- this.baseName = baseName(path);
50
- if (this.baseName.equals("[*]")) {
57
+ this.parentPath = compiledPath.getParentPath();
58
+
59
+ if (compiledRoot.getTailPath().equals("[*]")) {
51
60
  throw new ConfigException(String.format("%s wrongly ends with [*], perhaps you can remove the [*]", path));
52
61
  }
53
- this.baseIndex = baseIndex(path);
62
+ this.tailIndex = tailIndex(compiledRoot);
54
63
  this.parentPathValue = ValueFactory.newString(parentPath);
55
- this.baseNameValue = ValueFactory.newString(baseName);
64
+ String tailName = getTailName(compiledRoot);
65
+ this.tailNameValue = tailName == null ? ValueFactory.newNil() : ValueFactory.newString(tailName);
56
66
 
57
67
  this.srcValue = ValueFactory.newString(this.src);
58
- this.srcParentPath = parentPath(this.src);
59
- this.srcBaseName = baseName(this.src);
60
- this.srcBaseIndex = baseIndex(this.src);
68
+ this.srcParentPath = compiledSrc.getParentPath();
69
+ this.srcTailIndex = tailIndex(compiledSrcRoot);
61
70
  this.srcParentPathValue = ValueFactory.newString(this.srcParentPath);
62
- this.srcBaseNameValue = ValueFactory.newString(this.srcBaseName);
71
+ String srcTailName = getTailName(compiledSrcRoot);
72
+ this.srcTailNameValue = srcTailName == null ? ValueFactory.newNil() : ValueFactory.newString(srcTailName);
63
73
 
64
- if (! srcParentPath.equals(parentPath)) {
74
+ if (!srcParentPath.equals(parentPath)) {
65
75
  throw new ConfigException(String.format("The branch (parent path) of src \"%s\" must be same with of name \"%s\" yet", src, path));
66
76
  }
67
77
  }
68
78
 
79
+ // $['foo'] or $.foo => foo
80
+ // $['foo'][0] or $.foo[0] or $['foo'][*] or $.foo[*] => null
81
+ private String getTailName(RootPathToken root)
82
+ {
83
+ PathToken pathToken = root.getTail();
84
+ if (pathToken instanceof PropertyPathToken) {
85
+ if (!((PropertyPathToken) pathToken).singlePropertyCase()) {
86
+ throw new ConfigException(String.format("Multiple property is not supported \"%s\"", root.toString()));
87
+ }
88
+ return ((PropertyPathToken) pathToken).getProperties().get(0);
89
+ }
90
+ else {
91
+ return null;
92
+ }
93
+ }
94
+
95
+ private Long tailIndex(RootPathToken root)
96
+ {
97
+ PathToken tail = root.getTail();
98
+ if (tail instanceof ArrayPathToken) {
99
+ ArrayIndexOperation arrayIndexOperation = ((ArrayPathToken) tail).getArrayIndexOperation();
100
+ PathTokenUtil.assertSupportedArrayPathToken(arrayIndexOperation, path);
101
+ return arrayIndexOperation.indexes().get(0).longValue();
102
+ }
103
+ else {
104
+ return null;
105
+ }
106
+ }
107
+
69
108
  public String getPath()
70
109
  {
71
110
  return path;
@@ -96,14 +135,9 @@ public class JsonColumn
96
135
  return parentPath;
97
136
  }
98
137
 
99
- public String getBaseName()
100
- {
101
- return baseName;
102
- }
103
-
104
- public Long getBaseIndex()
138
+ public Long tailIndex()
105
139
  {
106
- return baseIndex;
140
+ return tailIndex;
107
141
  }
108
142
 
109
143
  public StringValue getParentPathValue()
@@ -111,9 +145,9 @@ public class JsonColumn
111
145
  return parentPathValue;
112
146
  }
113
147
 
114
- public StringValue getBaseNameValue()
148
+ public Value getTailNameValue()
115
149
  {
116
- return baseNameValue;
150
+ return tailNameValue;
117
151
  }
118
152
 
119
153
  public StringValue getSrcValue()
@@ -126,14 +160,9 @@ public class JsonColumn
126
160
  return srcParentPath;
127
161
  }
128
162
 
129
- public String getSrcBaseName()
130
- {
131
- return srcBaseName;
132
- }
133
-
134
- public Long getSrcBaseIndex()
163
+ public Long getSrcTailIndex()
135
164
  {
136
- return srcBaseIndex;
165
+ return srcTailIndex;
137
166
  }
138
167
 
139
168
  public StringValue getSrcParentPathValue()
@@ -141,51 +170,36 @@ public class JsonColumn
141
170
  return srcParentPathValue;
142
171
  }
143
172
 
144
- public StringValue getSrcBaseNameValue()
173
+ public Value getSrcTailNameValue()
145
174
  {
146
- return srcBaseNameValue;
175
+ return srcTailNameValue;
147
176
  }
148
177
 
149
178
  // like File.dirname
150
179
  public static String parentPath(String path)
151
180
  {
152
- String[] parts = path.split("\\.");
153
- StringBuilder builder = new StringBuilder();
154
- for (int i = 0; i < parts.length - 1; i++) {
155
- builder.append(".").append(parts[i]);
156
- }
157
- if (parts[parts.length - 1].contains("[")) {
158
- String[] arrayParts = parts[parts.length - 1].split("\\[");
159
- builder.append(".").append(arrayParts[0]);
160
- for (int j = 1; j < arrayParts.length - 1; j++) {
161
- builder.append("[").append(arrayParts[j]);
162
- }
163
- }
164
- return builder.deleteCharAt(0).toString();
181
+ return PathCompiler.compile(path).getParentPath();
165
182
  }
166
183
 
167
- public static String baseName(String path)
184
+ public static String tailName(String path)
168
185
  {
169
- String[] parts = path.split("\\.");
170
- String[] arrayParts = parts[parts.length - 1].split("\\[");
171
- if (arrayParts.length == 1) { // no [i]
172
- return arrayParts[arrayParts.length - 1];
173
- }
174
- else {
175
- return "[" + arrayParts[arrayParts.length - 1];
176
- }
186
+ return ((RootPathToken) PathCompiler.compile(path).getRoot()).getTailPath();
177
187
  }
178
188
 
179
- public static Long baseIndex(String path)
189
+ public static Long tailIndex(String path)
180
190
  {
181
- String baseName = baseName(path);
182
- if (baseName.startsWith("[") && baseName.endsWith("]")) {
183
- String baseIndex = baseName.substring(1, baseName.length() - 1);
184
- try {
185
- return Long.parseLong(baseIndex);
191
+ Path compiledPath = PathCompiler.compile(path);
192
+ PathToken tail = ((RootPathToken) compiledPath.getRoot()).getTail();
193
+ if (tail instanceof ArrayPathToken) {
194
+ ArrayIndexOperation arrayIndexOperation = ((ArrayPathToken) tail).getArrayIndexOperation();
195
+ if (arrayIndexOperation == null) {
196
+ throw new ConfigException(String.format("Array Slice Operation is not supported \"%s\"", path));
197
+ }
198
+ if (arrayIndexOperation.isSingleIndexOperation()) {
199
+ return arrayIndexOperation.indexes().get(0).longValue();
186
200
  }
187
- catch (NumberFormatException e) {
188
- return null;
201
+ else {
202
+ throw new ConfigException(String.format("Multi Array Indexes is not supported \"%s\"", path));
189
203
  }
190
204
  }
191
205
  else {
@@ -1,5 +1,8 @@
1
1
  package org.embulk.filter.column;
2
2
 
3
+ import com.dena.analytics.jsonpathcompiler.expressions.Path;
4
+ import com.dena.analytics.jsonpathcompiler.expressions.path.PathCompiler;
5
+ import com.dena.analytics.jsonpathcompiler.expressions.path.PathToken;
3
6
  import org.embulk.config.ConfigException;
4
7
  import org.embulk.filter.column.ColumnFilterPlugin.ColumnConfig;
5
8
  import org.embulk.filter.column.ColumnFilterPlugin.PluginTask;
@@ -80,29 +83,32 @@ public class JsonVisitor
80
83
 
81
84
  private void jsonColumnsPut(String path, JsonColumn value)
82
85
  {
83
- String parentPath = JsonColumn.parentPath(path);
86
+ Path compiledPath = PathCompiler.compile(path);
87
+ String parentPath = compiledPath.getParentPath();
84
88
  if (! jsonColumns.containsKey(parentPath)) {
85
89
  jsonColumns.put(parentPath, new LinkedHashMap<String, JsonColumn>());
86
90
  }
87
- jsonColumns.get(parentPath).put(path, value);
91
+ jsonColumns.get(parentPath).put(compiledPath.toString(), value);
88
92
  }
89
93
 
90
94
  private void jsonAddColumnsPut(String path, JsonColumn value)
91
95
  {
92
- String parentPath = JsonColumn.parentPath(path);
96
+ Path compiledPath = PathCompiler.compile(path);
97
+ String parentPath = compiledPath.getParentPath();
93
98
  if (! jsonAddColumns.containsKey(parentPath)) {
94
99
  jsonAddColumns.put(parentPath, new LinkedHashMap<String, JsonColumn>());
95
100
  }
96
- jsonAddColumns.get(parentPath).put(path, value);
101
+ jsonAddColumns.get(parentPath).put(compiledPath.toString(), value);
97
102
  }
98
103
 
99
104
  private void jsonDropColumnsPut(String path)
100
105
  {
101
- String parentPath = JsonColumn.parentPath(path);
106
+ Path compiledPath = PathCompiler.compile(path);
107
+ String parentPath = compiledPath.getParentPath();
102
108
  if (! jsonDropColumns.containsKey(parentPath)) {
103
109
  jsonDropColumns.put(parentPath, new HashSet<String>());
104
110
  }
105
- jsonDropColumns.get(parentPath).add(path);
111
+ jsonDropColumns.get(parentPath).add(compiledPath.toString());
106
112
  }
107
113
 
108
114
  // build jsonColumns, jsonAddColumns, and jsonDropColumns
@@ -117,7 +123,7 @@ public class JsonVisitor
117
123
  for (ColumnConfig dropColumn : dropColumns) {
118
124
  String name = dropColumn.getName();
119
125
  // skip NON json path notation to build output schema
120
- if (! name.startsWith("$.")) {
126
+ if (! PathCompiler.isProbablyJsonPath(name)) {
121
127
  continue;
122
128
  }
123
129
  jsonDropColumnsPut(name);
@@ -127,7 +133,7 @@ public class JsonVisitor
127
133
  for (ColumnConfig column : columns) {
128
134
  String name = column.getName();
129
135
  // skip NON json path notation to build output schema
130
- if (! name.startsWith("$.")) {
136
+ if (! PathCompiler.isProbablyJsonPath(name)) {
131
137
  continue;
132
138
  }
133
139
  if (column.getSrc().isPresent()) {
@@ -151,7 +157,7 @@ public class JsonVisitor
151
157
  for (ColumnConfig column : addColumns) {
152
158
  String name = column.getName();
153
159
  // skip NON json path notation to build output schema
154
- if (! name.startsWith("$.")) {
160
+ if (! PathCompiler.isProbablyJsonPath(name)) {
155
161
  continue;
156
162
  }
157
163
  if (column.getSrc().isPresent()) {
@@ -179,26 +185,19 @@ public class JsonVisitor
179
185
 
180
186
  for (ColumnConfig columnConfig : columnConfigs) {
181
187
  String name = columnConfig.getName();
182
- if (!name.startsWith("$.")) {
188
+ if (!PathCompiler.isProbablyJsonPath(name)) {
183
189
  continue;
184
190
  }
185
- String[] parts = name.split("\\.");
191
+ Path path = PathCompiler.compile(name);
192
+ PathToken parts = path.getRoot();
193
+ int count = parts.getTokenCount();
186
194
  StringBuilder partialPath = new StringBuilder("$");
187
- for (int i = 1; i < parts.length; i++) {
188
- if (parts[i].contains("[")) {
189
- String[] arrayParts = parts[i].split("\\[");
190
- partialPath.append(".").append(arrayParts[0]);
191
- this.shouldVisitSet.add(partialPath.toString());
192
- for (int j = 1; j < arrayParts.length; j++) {
193
- // Simply add [0] or [*] here
194
- partialPath.append("[").append(arrayParts[j]);
195
- this.shouldVisitSet.add(partialPath.toString());
196
- }
197
- }
198
- else {
199
- partialPath.append(".").append(parts[i]);
200
- this.shouldVisitSet.add(partialPath.toString());
201
- }
195
+ // skip "$"
196
+ for (int i = 1; i < count; i++) {
197
+ parts = parts.next();
198
+ PathTokenUtil.assertSupportedPathToken(parts, name);
199
+ partialPath.append(parts.getPathFragment().toString());
200
+ this.shouldVisitSet.add(partialPath.toString());
202
201
  }
203
202
  }
204
203
  }
@@ -220,7 +219,7 @@ public class JsonVisitor
220
219
  String newMapJsonPath(String rootPath, Value elementPathValue)
221
220
  {
222
221
  String elementPath = elementPathValue.asStringValue().asString();
223
- String newPath = new StringBuilder(rootPath).append(".").append(elementPath).toString();
222
+ String newPath = new StringBuilder(rootPath).append("['").append(elementPath).append("']").toString();
224
223
  return newPath;
225
224
  }
226
225
 
@@ -241,14 +240,14 @@ public class JsonVisitor
241
240
  }
242
241
  else if (this.jsonColumns.containsKey(rootPath)) {
243
242
  for (JsonColumn jsonColumn : this.jsonColumns.get(rootPath).values()) {
244
- int src = jsonColumn.getSrcBaseIndex().intValue();
243
+ int src = jsonColumn.getSrcTailIndex().intValue();
245
244
  Value v = (src < arrayValue.size() ? arrayValue.get(src) : null);
246
245
  if (v == null) {
247
246
  v = jsonColumn.getDefaultValue();
248
247
  }
249
248
  String newPath = jsonColumn.getPath();
250
249
  Value visited = visit(newPath, v);
251
- // int i = jsonColumn.getBaseIndex().intValue();
250
+ // int i = jsonColumn.tailIndex().intValue();
252
251
  // index is shifted, so j++ is used.
253
252
  newValue.add(j++, visited == null ? ValueFactory.newNil() : visited);
254
253
  }
@@ -262,7 +261,7 @@ public class JsonVisitor
262
261
  }
263
262
  if (this.jsonAddColumns.containsKey(rootPath)) {
264
263
  for (JsonColumn jsonColumn : this.jsonAddColumns.get(rootPath).values()) {
265
- int src = jsonColumn.getSrcBaseIndex().intValue();
264
+ int src = jsonColumn.getSrcTailIndex().intValue();
266
265
  Value v = (src < arrayValue.size() ? arrayValue.get(src) : null);
267
266
  if (v == null) {
268
267
  v = jsonColumn.getDefaultValue();
@@ -297,14 +296,14 @@ public class JsonVisitor
297
296
  else if (this.jsonColumns.containsKey(rootPath)) {
298
297
  Map<Value, Value> map = mapValue.map();
299
298
  for (JsonColumn jsonColumn : this.jsonColumns.get(rootPath).values()) {
300
- Value src = jsonColumn.getSrcBaseNameValue();
299
+ Value src = jsonColumn.getSrcTailNameValue();
301
300
  Value v = map.get(src);
302
301
  if (v == null) {
303
302
  v = jsonColumn.getDefaultValue();
304
303
  }
305
304
  String newPath = jsonColumn.getPath();
306
305
  Value visited = visit(newPath, v);
307
- newValue.add(i++, jsonColumn.getBaseNameValue());
306
+ newValue.add(i++, jsonColumn.getTailNameValue());
308
307
  newValue.add(i++, visited == null ? ValueFactory.newNil() : visited);
309
308
  }
310
309
  }
@@ -321,14 +320,14 @@ public class JsonVisitor
321
320
  if (this.jsonAddColumns.containsKey(rootPath)) {
322
321
  Map<Value, Value> map = mapValue.map();
323
322
  for (JsonColumn jsonColumn : this.jsonAddColumns.get(rootPath).values()) {
324
- Value src = jsonColumn.getSrcBaseNameValue();
323
+ Value src = jsonColumn.getSrcTailNameValue();
325
324
  Value v = map.get(src);
326
325
  if (v == null) {
327
326
  v = jsonColumn.getDefaultValue();
328
327
  }
329
328
  String newPath = jsonColumn.getPath();
330
329
  Value visited = visit(newPath, v);
331
- newValue.add(i++, jsonColumn.getBaseNameValue());
330
+ newValue.add(i++, jsonColumn.getTailNameValue());
332
331
  newValue.add(i++, visited == null ? ValueFactory.newNil() : visited);
333
332
  }
334
333
  }