Skip to content

Commit 2e8a973

Browse files
authored
Reinterpret dots in field names as object structure (#79922)
DocumentParser parses documents by following their object hierarchy, and using a parallel hierarchy of ObjectMappers to work out how to map leaf fields. Field names that contain dots complicate this, meaning that many methods need to reverse-engineer the object hierarchy to check that the current parent object mapper is the correct one; this is particularly complex when objects are being created dynamically. To simplify this logic, this commit introduces a DotExpandingXContentParser, which wraps another XContentParser and re-interprets any field name containing dots as a series of objects. So for example, `"foo.bar.baz":{ ... }` is represented as `"foo":{"bar":{"baz":{...}}}`. DocumentParser uses this to automatically expand all field names containing dots when parsing the source.
1 parent 0ed5eab commit 2e8a973

File tree

11 files changed

+714
-311
lines changed

11 files changed

+714
-311
lines changed
Lines changed: 244 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,244 @@
1+
/*
2+
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
3+
* or more contributor license agreements. Licensed under the Elastic License
4+
* 2.0 and the Server Side Public License, v 1; you may not use this file except
5+
* in compliance with, at your election, the Elastic License 2.0 or the Server
6+
* Side Public License, v 1.
7+
*/
8+
9+
package org.elasticsearch.xcontent;
10+
11+
import org.elasticsearch.core.CheckedFunction;
12+
import org.elasticsearch.core.RestApiVersion;
13+
14+
import java.io.IOException;
15+
import java.nio.CharBuffer;
16+
import java.util.List;
17+
import java.util.Map;
18+
import java.util.function.Supplier;
19+
20+
public abstract class DelegatingXContentParser implements XContentParser {
21+
22+
protected abstract XContentParser delegate();
23+
24+
@Override
25+
public XContentType contentType() {
26+
return delegate().contentType();
27+
}
28+
29+
@Override
30+
public void allowDuplicateKeys(boolean allowDuplicateKeys) {
31+
delegate().allowDuplicateKeys(allowDuplicateKeys);
32+
}
33+
34+
@Override
35+
public Token nextToken() throws IOException {
36+
return delegate().nextToken();
37+
}
38+
39+
@Override
40+
public void skipChildren() throws IOException {
41+
delegate().skipChildren();
42+
}
43+
44+
@Override
45+
public Token currentToken() {
46+
return delegate().currentToken();
47+
}
48+
49+
@Override
50+
public String currentName() throws IOException {
51+
return delegate().currentName();
52+
}
53+
54+
@Override
55+
public Map<String, Object> map() throws IOException {
56+
return delegate().map();
57+
}
58+
59+
@Override
60+
public Map<String, Object> mapOrdered() throws IOException {
61+
return delegate().mapOrdered();
62+
}
63+
64+
@Override
65+
public Map<String, String> mapStrings() throws IOException {
66+
return delegate().mapStrings();
67+
}
68+
69+
@Override
70+
public <T> Map<String, T> map(Supplier<Map<String, T>> mapFactory, CheckedFunction<XContentParser, T, IOException> mapValueParser)
71+
throws IOException {
72+
return delegate().map(mapFactory, mapValueParser);
73+
}
74+
75+
@Override
76+
public List<Object> list() throws IOException {
77+
return delegate().list();
78+
}
79+
80+
@Override
81+
public List<Object> listOrderedMap() throws IOException {
82+
return delegate().listOrderedMap();
83+
}
84+
85+
@Override
86+
public String text() throws IOException {
87+
return delegate().text();
88+
}
89+
90+
@Override
91+
public String textOrNull() throws IOException {
92+
return delegate().textOrNull();
93+
}
94+
95+
@Override
96+
public CharBuffer charBufferOrNull() throws IOException {
97+
return delegate().charBufferOrNull();
98+
}
99+
100+
@Override
101+
public CharBuffer charBuffer() throws IOException {
102+
return delegate().charBuffer();
103+
}
104+
105+
@Override
106+
public Object objectText() throws IOException {
107+
return delegate().objectText();
108+
}
109+
110+
@Override
111+
public Object objectBytes() throws IOException {
112+
return delegate().objectBytes();
113+
}
114+
115+
@Override
116+
public boolean hasTextCharacters() {
117+
return delegate().hasTextCharacters();
118+
}
119+
120+
@Override
121+
public char[] textCharacters() throws IOException {
122+
return delegate().textCharacters();
123+
}
124+
125+
@Override
126+
public int textLength() throws IOException {
127+
return delegate().textLength();
128+
}
129+
130+
@Override
131+
public int textOffset() throws IOException {
132+
return delegate().textOffset();
133+
}
134+
135+
@Override
136+
public Number numberValue() throws IOException {
137+
return delegate().numberValue();
138+
}
139+
140+
@Override
141+
public NumberType numberType() throws IOException {
142+
return delegate().numberType();
143+
}
144+
145+
@Override
146+
public short shortValue(boolean coerce) throws IOException {
147+
return delegate().shortValue(coerce);
148+
}
149+
150+
@Override
151+
public int intValue(boolean coerce) throws IOException {
152+
return delegate().intValue(coerce);
153+
}
154+
155+
@Override
156+
public long longValue(boolean coerce) throws IOException {
157+
return delegate().longValue(coerce);
158+
}
159+
160+
@Override
161+
public float floatValue(boolean coerce) throws IOException {
162+
return delegate().floatValue(coerce);
163+
}
164+
165+
@Override
166+
public double doubleValue(boolean coerce) throws IOException {
167+
return delegate().doubleValue(coerce);
168+
}
169+
170+
@Override
171+
public short shortValue() throws IOException {
172+
return delegate().shortValue();
173+
}
174+
175+
@Override
176+
public int intValue() throws IOException {
177+
return delegate().intValue();
178+
}
179+
180+
@Override
181+
public long longValue() throws IOException {
182+
return delegate().longValue();
183+
}
184+
185+
@Override
186+
public float floatValue() throws IOException {
187+
return delegate().floatValue();
188+
}
189+
190+
@Override
191+
public double doubleValue() throws IOException {
192+
return delegate().doubleValue();
193+
}
194+
195+
@Override
196+
public boolean isBooleanValue() throws IOException {
197+
return delegate().isBooleanValue();
198+
}
199+
200+
@Override
201+
public boolean booleanValue() throws IOException {
202+
return delegate().booleanValue();
203+
}
204+
205+
@Override
206+
public byte[] binaryValue() throws IOException {
207+
return delegate().binaryValue();
208+
}
209+
210+
@Override
211+
public XContentLocation getTokenLocation() {
212+
return delegate().getTokenLocation();
213+
}
214+
215+
@Override
216+
public <T> T namedObject(Class<T> categoryClass, String name, Object context) throws IOException {
217+
return delegate().namedObject(categoryClass, name, context);
218+
}
219+
220+
@Override
221+
public NamedXContentRegistry getXContentRegistry() {
222+
return delegate().getXContentRegistry();
223+
}
224+
225+
@Override
226+
public boolean isClosed() {
227+
return delegate().isClosed();
228+
}
229+
230+
@Override
231+
public RestApiVersion getRestApiVersion() {
232+
return delegate().getRestApiVersion();
233+
}
234+
235+
@Override
236+
public DeprecationHandler getDeprecationHandler() {
237+
return delegate().getDeprecationHandler();
238+
}
239+
240+
@Override
241+
public void close() throws IOException {
242+
delegate().close();
243+
}
244+
}

0 commit comments

Comments
 (0)