Skip to content

Commit b92cce7

Browse files
Add buffered JsonData implementation for Jackson (#567) (#568)
Co-authored-by: Sylvain Wallez <[email protected]>
1 parent 6708eba commit b92cce7

File tree

11 files changed

+322
-56
lines changed

11 files changed

+322
-56
lines changed
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
/*
2+
* Licensed to Elasticsearch B.V. under one or more contributor
3+
* license agreements. See the NOTICE file distributed with
4+
* this work for additional information regarding copyright
5+
* ownership. Elasticsearch B.V. licenses this file to you under
6+
* the Apache License, Version 2.0 (the "License"); you may
7+
* not use this file except in compliance with the License.
8+
* You may obtain a copy of the License at
9+
*
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing,
13+
* software distributed under the License is distributed on an
14+
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15+
* KIND, either express or implied. See the License for the
16+
* specific language governing permissions and limitations
17+
* under the License.
18+
*/
19+
20+
package co.elastic.clients.json;
21+
22+
import jakarta.json.stream.JsonParser;
23+
24+
public interface BufferingJsonParser extends JsonParser {
25+
26+
/**
27+
* Get the value at the current parser position as a <code>JsonData</code> object.
28+
* @return
29+
*/
30+
JsonData getJsonData();
31+
32+
}
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
/*
2+
* Licensed to Elasticsearch B.V. under one or more contributor
3+
* license agreements. See the NOTICE file distributed with
4+
* this work for additional information regarding copyright
5+
* ownership. Elasticsearch B.V. licenses this file to you under
6+
* the Apache License, Version 2.0 (the "License"); you may
7+
* not use this file except in compliance with the License.
8+
* You may obtain a copy of the License at
9+
*
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing,
13+
* software distributed under the License is distributed on an
14+
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15+
* KIND, either express or implied. See the License for the
16+
* specific language governing permissions and limitations
17+
* under the License.
18+
*/
19+
20+
package co.elastic.clients.json;
21+
22+
import jakarta.json.stream.JsonParser;
23+
24+
/**
25+
* A buffer of JSON events.
26+
*/
27+
public interface JsonBuffer {
28+
29+
/**
30+
* Get the contents of this buffer as a JSON parser. Can be called multiple times.
31+
*/
32+
JsonParser asParser();
33+
}

java-client/src/main/java/co/elastic/clients/json/JsonData.java

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,9 @@ public interface JsonData extends JsonpSerializable {
5858
*
5959
* @throws IllegalStateException if no mapper was provided at creation time.
6060
*/
61-
<T> T to(Class<T> clazz);
61+
default <T> T to(Class<T> clazz) {
62+
return to((Type)clazz);
63+
}
6264

6365
/**
6466
* Converts this object to a target type. A mapper must have been provided at creation time.
@@ -70,7 +72,9 @@ public interface JsonData extends JsonpSerializable {
7072
/**
7173
* Converts this object to a target class.
7274
*/
73-
<T> T to(Class<T> clazz, JsonpMapper mapper);
75+
default <T> T to(Class<T> clazz, JsonpMapper mapper) {
76+
return to((Type)clazz, mapper);
77+
}
7478

7579
/**
7680
* Converts this object to a target type.
@@ -145,8 +149,7 @@ static JsonData from(InputStream json) {
145149
* {@link #deserialize(JsonpDeserializer)}.
146150
*/
147151
static JsonData from(JsonParser parser, JsonpMapper mapper) {
148-
parser.next(); // Need to be at the beginning of the value to read
149-
return of(parser.getValue(), mapper);
152+
return from(parser, mapper, parser.next());
150153
}
151154

152155
/**
@@ -155,7 +158,11 @@ static JsonData from(JsonParser parser, JsonpMapper mapper) {
155158
* {@link #deserialize(JsonpDeserializer)}.
156159
*/
157160
static JsonData from(JsonParser parser, JsonpMapper mapper, JsonParser.Event event) {
158-
return of(parser.getValue(), mapper);
161+
if (parser instanceof BufferingJsonParser) {
162+
return ((BufferingJsonParser)parser).getJsonData();
163+
} else {
164+
return of(parser.getValue(), mapper);
165+
}
159166
}
160167

161168
JsonpDeserializer<JsonData> _DESERIALIZER = JsonpDeserializer.of(

java-client/src/main/java/co/elastic/clients/json/JsonDataImpl.java

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -64,21 +64,11 @@ public JsonValue toJson(JsonpMapper mapper) {
6464
return parser.getValue();
6565
}
6666

67-
@Override
68-
public <T> T to(Class<T> clazz) {
69-
return to((Type)clazz, null);
70-
}
71-
7267
@Override
7368
public <T> T to(Type clazz) {
7469
return to(clazz, null);
7570
}
7671

77-
@Override
78-
public <T> T to(Class<T> clazz, JsonpMapper mapper) {
79-
return to((Type)clazz, mapper);
80-
}
81-
8272
@Override
8373
public <T> T to(Type type, JsonpMapper mapper) {
8474
if (type instanceof Class<?> && ((Class<?>)type).isAssignableFrom(value.getClass())) {

java-client/src/main/java/co/elastic/clients/json/JsonpUtils.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -150,6 +150,13 @@ public static void skipValue(JsonParser parser, Event event) {
150150
}
151151
}
152152

153+
/**
154+
* Copy the JSON value at the current parser location to a JSON generator.
155+
*/
156+
public static void copy(JsonParser parser, JsonGenerator generator) {
157+
copy(parser, generator, parser.next());
158+
}
159+
153160
/**
154161
* Copy the JSON value at the current parser location to a JSON generator.
155162
*/
Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
/*
2+
* Licensed to Elasticsearch B.V. under one or more contributor
3+
* license agreements. See the NOTICE file distributed with
4+
* this work for additional information regarding copyright
5+
* ownership. Elasticsearch B.V. licenses this file to you under
6+
* the Apache License, Version 2.0 (the "License"); you may
7+
* not use this file except in compliance with the License.
8+
* You may obtain a copy of the License at
9+
*
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing,
13+
* software distributed under the License is distributed on an
14+
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15+
* KIND, either express or implied. See the License for the
16+
* specific language governing permissions and limitations
17+
* under the License.
18+
*/
19+
20+
package co.elastic.clients.json.jackson;
21+
22+
import co.elastic.clients.json.JsonBuffer;
23+
import co.elastic.clients.json.JsonData;
24+
import co.elastic.clients.json.JsonpDeserializer;
25+
import co.elastic.clients.json.JsonpMapper;
26+
import co.elastic.clients.json.JsonpUtils;
27+
import com.fasterxml.jackson.databind.util.TokenBuffer;
28+
import jakarta.json.JsonValue;
29+
import jakarta.json.stream.JsonGenerator;
30+
import jakarta.json.stream.JsonParser;
31+
32+
import java.io.IOException;
33+
import java.lang.reflect.Type;
34+
35+
class JacksonJsonBuffer implements JsonBuffer, JsonData {
36+
private final TokenBuffer buffer;
37+
private final JacksonJsonpMapper mapper;
38+
39+
JacksonJsonBuffer(TokenBuffer buffer, JacksonJsonpMapper mapper) {
40+
this.buffer = buffer;
41+
this.mapper = mapper;
42+
}
43+
44+
@Override
45+
public JsonParser asParser() {
46+
return new JacksonJsonpParser(buffer.asParser(), mapper);
47+
}
48+
49+
@Override
50+
public JsonValue toJson() {
51+
try (JsonParser parser = asParser()) {
52+
parser.next(); // move to first event
53+
return parser.getValue();
54+
}
55+
}
56+
57+
@Override
58+
public JsonValue toJson(JsonpMapper mapper) {
59+
// We don't need the mapper
60+
return toJson();
61+
}
62+
63+
@Override
64+
public <T> T to(Type type) {
65+
return to(type, this.mapper);
66+
}
67+
68+
@Override
69+
public <T> T to(Type type, JsonpMapper mapper) {
70+
try (JsonParser parser = asParser()) {
71+
return mapper.deserialize(parser, type);
72+
}
73+
}
74+
75+
@Override
76+
public <T> T deserialize(JsonpDeserializer<T> deserializer) {
77+
return deserialize(deserializer, this.mapper);
78+
}
79+
80+
@Override
81+
public <T> T deserialize(JsonpDeserializer<T> deserializer, JsonpMapper mapper) {
82+
try (JsonParser parser = asParser()) {
83+
return deserializer.deserialize(parser, mapper);
84+
}
85+
}
86+
87+
@Override
88+
public void serialize(JsonGenerator generator, JsonpMapper mapper) {
89+
if (generator instanceof JacksonJsonpGenerator) {
90+
JacksonJsonpGenerator jkGenerator = (JacksonJsonpGenerator) generator;
91+
try {
92+
buffer.serialize(jkGenerator.jacksonGenerator());
93+
} catch (IOException e) {
94+
throw JacksonUtils.convertException(e);
95+
}
96+
} else {
97+
try (JsonParser parser = asParser()) {
98+
JsonpUtils.copy(parser, generator);
99+
}
100+
}
101+
}
102+
}

java-client/src/main/java/co/elastic/clients/json/jackson/JacksonJsonProvider.java

Lines changed: 10 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -52,21 +52,20 @@
5252
*/
5353
public class JacksonJsonProvider extends JsonProvider {
5454

55+
private final JacksonJsonpMapper mapper;
5556
private final JsonFactory jsonFactory;
5657

57-
public JacksonJsonProvider(JsonFactory jsonFactory) {
58-
this.jsonFactory = jsonFactory;
58+
public JacksonJsonProvider(JacksonJsonpMapper mapper) {
59+
this.mapper = mapper;
60+
this.jsonFactory = mapper.objectMapper().getFactory();
5961
}
6062

6163
public JacksonJsonProvider() {
62-
this(new JsonFactory());
64+
this(new JacksonJsonpMapper());
6365
}
6466

65-
/**
66-
* Return the underlying Jackson {@link JsonFactory}.
67-
*/
68-
public JsonFactory jacksonJsonFactory() {
69-
return this.jsonFactory;
67+
public JacksonJsonpMapper mapper() {
68+
return this.mapper;
7069
}
7170

7271
//---------------------------------------------------------------------------------------------
@@ -105,7 +104,7 @@ private class ParserFactory implements JsonParserFactory {
105104
@Override
106105
public JsonParser createParser(Reader reader) {
107106
try {
108-
return new JacksonJsonpParser(jsonFactory.createParser(reader));
107+
return new JacksonJsonpParser(jsonFactory.createParser(reader), mapper);
109108
} catch (IOException ioe) {
110109
throw JacksonUtils.convertException(ioe);
111110
}
@@ -114,7 +113,7 @@ public JsonParser createParser(Reader reader) {
114113
@Override
115114
public JsonParser createParser(InputStream in) {
116115
try {
117-
return new JacksonJsonpParser(jsonFactory.createParser(in));
116+
return new JacksonJsonpParser(jsonFactory.createParser(in), mapper);
118117
} catch (IOException ioe) {
119118
throw JacksonUtils.convertException(ioe);
120119
}
@@ -123,7 +122,7 @@ public JsonParser createParser(InputStream in) {
123122
@Override
124123
public JsonParser createParser(InputStream in, Charset charset) {
125124
try {
126-
return new JacksonJsonpParser(jsonFactory.createParser(new InputStreamReader(in, charset)));
125+
return new JacksonJsonpParser(jsonFactory.createParser(new InputStreamReader(in, charset)), mapper);
127126
} catch (IOException ioe) {
128127
throw JacksonUtils.convertException(ioe);
129128
}

java-client/src/main/java/co/elastic/clients/json/jackson/JacksonJsonpMapper.java

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -46,10 +46,9 @@ private JacksonJsonpMapper(ObjectMapper objectMapper, JacksonJsonProvider provid
4646
}
4747

4848
public JacksonJsonpMapper(ObjectMapper objectMapper) {
49-
this(objectMapper,
50-
// Creating the json factory from the mapper ensures it will be returned by JsonParser.getCodec()
51-
new JacksonJsonProvider(objectMapper.getFactory())
52-
);
49+
this.objectMapper = objectMapper;
50+
// Order is important as JacksonJsonProvider(this) will get ObjectMapper
51+
this.provider = new JacksonJsonProvider(this);
5352
}
5453

5554
public JacksonJsonpMapper() {

0 commit comments

Comments
 (0)