Skip to content

Commit 67fe595

Browse files
committed
GH-5744: Migrate rdf4j-queryresultio-sparqljson to Jackson 3.1.2
Update jackson-core dependency to tools.jackson.core group at version 3.1.2 (managed via jackson3.version property in root pom). Java code changes following the Jackson 3 migration guide: - Update all imports from com.fasterxml.jackson to tools.jackson (jackson-annotations excluded as per Jackson 3 design) - JsonFactory/JsonFactoryBuilder moved to tools.jackson.core.json package - JsonProcessingException renamed to JacksonException (now unchecked) - JsonParser: getCurrentToken/Name/Location() → currentToken/Name/Location() - JsonParser: getParsingContext() → streamReadContext() - JsonParser: nextTextValue() → nextStringValue() - JsonToken.FIELD_NAME → JsonToken.PROPERTY_NAME - JsonGenerator: writeFieldName() → writeName() - JsonGenerator write*Field/FieldStart → write*Property/PropertyStart - JsonReadFeature.ALLOW_UNQUOTED_FIELD_NAMES → ALLOW_UNQUOTED_PROPERTY_NAMES - JsonFactory.Feature.INTERN/CANONICALIZE_FIELD_NAMES removed - ObjectMapper is immutable: configure pretty printer via ObjectWriteContext at generator creation time instead of setPrettyPrinter() - catch(IOException) → catch(JacksonException) for Jackson call sites
1 parent 7790747 commit 67fe595

6 files changed

Lines changed: 159 additions & 152 deletions

File tree

core/queryresultio/sparqljson/pom.xml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,9 @@
2626
<version>${project.version}</version>
2727
</dependency>
2828
<dependency>
29-
<groupId>com.fasterxml.jackson.core</groupId>
29+
<groupId>tools.jackson.core</groupId>
3030
<artifactId>jackson-core</artifactId>
31+
<version>${jackson3.version}</version>
3132
</dependency>
3233
<dependency>
3334
<groupId>${project.groupId}</groupId>

core/queryresultio/sparqljson/src/main/java/org/eclipse/rdf4j/query/resultio/sparqljson/AbstractSPARQLJSONParser.java

Lines changed: 74 additions & 74 deletions
Original file line numberDiff line numberDiff line change
@@ -41,14 +41,14 @@
4141
import org.slf4j.Logger;
4242
import org.slf4j.LoggerFactory;
4343

44-
import com.fasterxml.jackson.core.JsonFactory;
45-
import com.fasterxml.jackson.core.JsonFactoryBuilder;
46-
import com.fasterxml.jackson.core.JsonParser;
47-
import com.fasterxml.jackson.core.JsonProcessingException;
48-
import com.fasterxml.jackson.core.JsonToken;
49-
import com.fasterxml.jackson.core.StreamReadFeature;
50-
import com.fasterxml.jackson.core.StreamWriteFeature;
51-
import com.fasterxml.jackson.core.json.JsonReadFeature;
44+
import tools.jackson.core.JacksonException;
45+
import tools.jackson.core.JsonParser;
46+
import tools.jackson.core.JsonToken;
47+
import tools.jackson.core.StreamReadFeature;
48+
import tools.jackson.core.StreamWriteFeature;
49+
import tools.jackson.core.TokenStreamFactory;
50+
import tools.jackson.core.json.JsonFactory;
51+
import tools.jackson.core.json.JsonReadFeature;
5252

5353
/**
5454
* Abstract base class for SPARQL Results JSON Parsers. Provides a common implementation of both boolean and tuple
@@ -134,7 +134,7 @@ protected boolean parseQueryResultInternal(InputStream in, boolean attemptParseB
134134

135135
if (jp.nextToken() != JsonToken.START_OBJECT) {
136136
throw new QueryResultParseException("Expected SPARQL Results JSON document to start with an Object",
137-
jp.getCurrentLocation().getLineNr(), jp.getCurrentLocation().getColumnNr());
137+
jp.currentLocation().getLineNr(), jp.currentLocation().getColumnNr());
138138
}
139139

140140
List<String> varsList = new ArrayList<>();
@@ -143,27 +143,27 @@ protected boolean parseQueryResultInternal(InputStream in, boolean attemptParseB
143143

144144
while (jp.nextToken() != JsonToken.END_OBJECT) {
145145

146-
final String baseStr = jp.getCurrentName();
146+
final String baseStr = jp.currentName();
147147

148148
if (baseStr.equals(HEAD)) {
149149
if (jp.nextToken() != JsonToken.START_OBJECT) {
150150
throw new QueryResultParseException("Did not find object under " + baseStr + " field",
151-
jp.getCurrentLocation().getLineNr(), jp.getCurrentLocation().getColumnNr());
151+
jp.currentLocation().getLineNr(), jp.currentLocation().getColumnNr());
152152
}
153153

154154
while (jp.nextToken() != JsonToken.END_OBJECT) {
155-
final String headStr = jp.getCurrentName();
155+
final String headStr = jp.currentName();
156156

157157
if (headStr.equals(VARS)) {
158158
if (!attemptParseTuple) {
159159
throw new QueryResultParseException(
160160
"Found tuple results variables when attempting to parse SPARQL Results JSON to boolean result",
161-
jp.getCurrentLocation().getLineNr(), jp.getCurrentLocation().getLineNr());
161+
jp.currentLocation().getLineNr(), jp.currentLocation().getColumnNr());
162162
}
163163

164164
if (jp.nextToken() != JsonToken.START_ARRAY) {
165165
throw new QueryResultParseException("Expected variable labels to be an array",
166-
jp.getCurrentLocation().getLineNr(), jp.getCurrentLocation().getColumnNr());
166+
jp.currentLocation().getLineNr(), jp.currentLocation().getColumnNr());
167167
}
168168

169169
while (jp.nextToken() != JsonToken.END_ARRAY) {
@@ -190,7 +190,7 @@ protected boolean parseQueryResultInternal(InputStream in, boolean attemptParseB
190190
List<String> linksList = new ArrayList<>();
191191
if (jp.nextToken() != JsonToken.START_ARRAY) {
192192
throw new QueryResultParseException("Expected links to be an array",
193-
jp.getCurrentLocation().getLineNr(), jp.getCurrentLocation().getColumnNr());
193+
jp.currentLocation().getLineNr(), jp.currentLocation().getColumnNr());
194194
}
195195

196196
while (jp.nextToken() != JsonToken.END_ARRAY) {
@@ -203,48 +203,48 @@ protected boolean parseQueryResultInternal(InputStream in, boolean attemptParseB
203203

204204
} else {
205205
throw new QueryResultParseException("Found unexpected object in head field: " + headStr,
206-
jp.getCurrentLocation().getLineNr(), jp.getCurrentLocation().getColumnNr());
206+
jp.currentLocation().getLineNr(), jp.currentLocation().getColumnNr());
207207
}
208208
}
209209
} else if (baseStr.equals(RESULTS)) {
210210
if (!attemptParseTuple) {
211211
throw new QueryResultParseException(
212212
"Found tuple results bindings when attempting to parse SPARQL Results JSON to boolean result",
213-
jp.getCurrentLocation().getLineNr(), jp.getCurrentLocation().getLineNr());
213+
jp.currentLocation().getLineNr(), jp.currentLocation().getColumnNr());
214214
}
215215
if (jp.nextToken() != JsonToken.START_OBJECT) {
216216
throw new QueryResultParseException(
217-
"Found unexpected token in results object: " + jp.getCurrentName(),
218-
jp.getCurrentLocation().getLineNr(), jp.getCurrentLocation().getColumnNr());
217+
"Found unexpected token in results object: " + jp.currentName(),
218+
jp.currentLocation().getLineNr(), jp.currentLocation().getColumnNr());
219219
}
220220

221221
while (jp.nextToken() != JsonToken.END_OBJECT) {
222222

223-
if (jp.getCurrentName().equals(BINDINGS)) {
223+
if (jp.currentName().equals(BINDINGS)) {
224224
if (jp.nextToken() != JsonToken.START_ARRAY) {
225225
throw new QueryResultParseException("Found unexpected token in bindings object",
226-
jp.getCurrentLocation().getLineNr(), jp.getCurrentLocation().getColumnNr());
226+
jp.currentLocation().getLineNr(), jp.currentLocation().getColumnNr());
227227
}
228228

229229
while (jp.nextToken() != JsonToken.END_ARRAY) {
230230

231231
MapBindingSet nextBindingSet = new MapBindingSet();
232232

233-
if (jp.getCurrentToken() != JsonToken.START_OBJECT) {
233+
if (jp.currentToken() != JsonToken.START_OBJECT) {
234234
throw new QueryResultParseException(
235-
"Did not find object in bindings array: " + jp.getCurrentName(),
236-
jp.getCurrentLocation().getLineNr(), jp.getCurrentLocation().getColumnNr());
235+
"Did not find object in bindings array: " + jp.currentName(),
236+
jp.currentLocation().getLineNr(), jp.currentLocation().getColumnNr());
237237
}
238238

239239
while (jp.nextToken() != JsonToken.END_OBJECT) {
240240

241-
if (jp.getCurrentToken() != JsonToken.FIELD_NAME) {
241+
if (jp.currentToken() != JsonToken.PROPERTY_NAME) {
242242
throw new QueryResultParseException("Did not find binding name",
243-
jp.getCurrentLocation().getLineNr(),
244-
jp.getCurrentLocation().getColumnNr());
243+
jp.currentLocation().getLineNr(),
244+
jp.currentLocation().getColumnNr());
245245
}
246246

247-
final String bindingStr = jp.getCurrentName();
247+
final String bindingStr = jp.currentName();
248248

249249
nextBindingSet.addBinding(bindingStr, parseValue(jp, bindingStr));
250250
}
@@ -266,19 +266,19 @@ protected boolean parseQueryResultInternal(InputStream in, boolean attemptParseB
266266
}
267267
// Backwards compatibility with very old draft of the original
268268
// SPARQL spec
269-
else if (jp.getCurrentName().equals(DISTINCT) || jp.getCurrentName().equals(ORDERED)) {
269+
else if (jp.currentName().equals(DISTINCT) || jp.currentName().equals(ORDERED)) {
270270
jp.nextToken();
271271
} else {
272272
throw new QueryResultParseException(
273-
"Found unexpected field in results: " + jp.getCurrentName(),
274-
jp.getCurrentLocation().getLineNr(), jp.getCurrentLocation().getColumnNr());
273+
"Found unexpected field in results: " + jp.currentName(),
274+
jp.currentLocation().getLineNr(), jp.currentLocation().getColumnNr());
275275
}
276276
}
277277
} else if (baseStr.equals(BOOLEAN)) {
278278
if (!attemptParseBoolean) {
279279
throw new QueryResultParseException(
280280
"Found boolean results when attempting to parse SPARQL Results JSON to tuple results",
281-
jp.getCurrentLocation().getLineNr(), jp.getCurrentLocation().getLineNr());
281+
jp.currentLocation().getLineNr(), jp.currentLocation().getColumnNr());
282282
}
283283
jp.nextToken();
284284

@@ -288,35 +288,35 @@ else if (jp.getCurrentName().equals(DISTINCT) || jp.getCurrentName().equals(ORDE
288288
}
289289
} else {
290290
logger.debug("Found unexpected object in top level {} field #{}.{}", baseStr,
291-
jp.getCurrentLocation().getLineNr(), jp.getCurrentLocation().getColumnNr());
291+
jp.currentLocation().getLineNr(), jp.currentLocation().getColumnNr());
292292
// Consume the discovered unexpected object
293293
// (in particular, if it is either an array or a composite object).
294294
jp.nextToken();
295295

296296
if (jp.currentToken() == JsonToken.START_ARRAY) {
297-
while (!(jp.getParsingContext().getParent().inRoot()
297+
while (!(jp.streamReadContext().getParent().inRoot()
298298
&& (jp.currentToken() == JsonToken.END_ARRAY))) {
299299
if (jp.nextToken() == null) {
300300
throw new QueryResultParseException(
301301
"An array value of the unexpected " + baseStr + " field is not closed.",
302-
jp.getCurrentLocation().getLineNr(), jp.getCurrentLocation().getLineNr());
302+
jp.currentLocation().getLineNr(), jp.currentLocation().getColumnNr());
303303
}
304304
}
305305
} else if (jp.currentToken() == JsonToken.START_OBJECT) {
306-
while (!(jp.getParsingContext().getParent().inRoot()
306+
while (!(jp.streamReadContext().getParent().inRoot()
307307
&& (jp.currentToken() == JsonToken.END_OBJECT))) {
308308
if (jp.nextToken() == null) {
309309
throw new QueryResultParseException(
310310
"An object value of the unexpected " + baseStr + " field is not closed.",
311-
jp.getCurrentLocation().getLineNr(), jp.getCurrentLocation().getLineNr());
311+
jp.currentLocation().getLineNr(), jp.currentLocation().getColumnNr());
312312
}
313313
}
314314
}
315315
}
316316
}
317-
} catch (JsonProcessingException e) {
317+
} catch (JacksonException e) {
318318
throw new QueryResultParseException("Could not parse SPARQL/JSON", e, e.getLocation().getLineNr(),
319-
e.getLocation().getLineNr());
319+
e.getLocation().getColumnNr());
320320
}
321321

322322
return result;
@@ -325,8 +325,8 @@ else if (jp.getCurrentName().equals(DISTINCT) || jp.getCurrentName().equals(ORDE
325325
protected Value parseValue(JsonParser jp, String bindingStr) throws IOException {
326326
if (jp.nextToken() != JsonToken.START_OBJECT) {
327327
throw new QueryResultParseException("Did not find object for binding value",
328-
jp.getCurrentLocation().getLineNr(),
329-
jp.getCurrentLocation().getColumnNr());
328+
jp.currentLocation().getLineNr(),
329+
jp.currentLocation().getColumnNr());
330330
}
331331

332332
String lang = null;
@@ -337,42 +337,42 @@ protected Value parseValue(JsonParser jp, String bindingStr) throws IOException
337337
Triple triple = null;
338338

339339
while (jp.nextToken() != JsonToken.END_OBJECT) {
340-
if (jp.getCurrentToken() != JsonToken.FIELD_NAME) {
340+
if (jp.currentToken() != JsonToken.PROPERTY_NAME) {
341341
throw new QueryResultParseException(
342342
"Did not find value attribute under " + bindingStr + " field",
343-
jp.getCurrentLocation().getLineNr(),
344-
jp.getCurrentLocation().getColumnNr());
343+
jp.currentLocation().getLineNr(),
344+
jp.currentLocation().getColumnNr());
345345
}
346-
String fieldName = jp.getCurrentName();
346+
String fieldName = jp.currentName();
347347

348348
// set the appropriate state variable
349349
if (TYPE.equals(fieldName)) {
350-
type = jp.nextTextValue();
350+
type = jp.nextStringValue();
351351
if (TRIPLE_STARDOG.equals(type)) {
352352
// Stardog RDF-star serialization dialect does not wrap the triple in a value object
353353
triple = parseStardogTripleValue(jp, type);
354354
// avoid reading away the next end-of-object token by jumping out of the loop.
355355
break;
356356
}
357357
} else if (XMLLANG.equals(fieldName)) {
358-
lang = jp.nextTextValue();
358+
lang = jp.nextStringValue();
359359
} else if (DATATYPE.equals(fieldName)) {
360-
datatype = jp.nextTextValue();
360+
datatype = jp.nextStringValue();
361361
} else if (VALUE.equals(fieldName)) {
362362
if (jp.nextToken() == JsonToken.START_OBJECT) {
363363
triple = parseTripleValue(jp, fieldName);
364-
if (jp.getCurrentToken() != JsonToken.END_OBJECT) {
365-
throw new QueryResultParseException("Unexpected token: " + jp.getCurrentName(),
366-
jp.getCurrentLocation().getLineNr(),
367-
jp.getCurrentLocation().getColumnNr());
364+
if (jp.currentToken() != JsonToken.END_OBJECT) {
365+
throw new QueryResultParseException("Unexpected token: " + jp.currentName(),
366+
jp.currentLocation().getLineNr(),
367+
jp.currentLocation().getColumnNr());
368368
}
369369
} else {
370370
value = jp.getText();
371371
}
372372
} else {
373373
throw new QueryResultParseException("Unexpected field name: " + fieldName,
374-
jp.getCurrentLocation().getLineNr(),
375-
jp.getCurrentLocation().getColumnNr());
374+
jp.currentLocation().getLineNr(),
375+
jp.currentLocation().getColumnNr());
376376

377377
}
378378
}
@@ -387,58 +387,58 @@ private Triple parseStardogTripleValue(JsonParser jp, String fieldName) throws I
387387
Value subject = null, predicate = null, object = null;
388388

389389
while (jp.nextToken() != JsonToken.END_OBJECT) {
390-
if (jp.getCurrentToken() != JsonToken.FIELD_NAME) {
390+
if (jp.currentToken() != JsonToken.PROPERTY_NAME) {
391391
throw new QueryResultParseException("Did not find triple attribute in triple value",
392-
jp.getCurrentLocation().getLineNr(),
393-
jp.getCurrentLocation().getColumnNr());
392+
jp.currentLocation().getLineNr(),
393+
jp.currentLocation().getColumnNr());
394394
}
395-
String posName = jp.getCurrentName();
395+
String posName = jp.currentName();
396396
if (SUBJECT.equals(posName)) {
397397
if (subject != null) {
398398
throw new QueryResultParseException(
399399
posName + " field encountered twice in triple value: ",
400-
jp.getCurrentLocation().getLineNr(),
401-
jp.getCurrentLocation().getColumnNr());
400+
jp.currentLocation().getLineNr(),
401+
jp.currentLocation().getColumnNr());
402402
}
403403
subject = parseValue(jp, fieldName + ":" + posName);
404404
} else if (PREDICATE.equals(posName)) {
405405
if (predicate != null) {
406406
throw new QueryResultParseException(
407407
posName + " field encountered twice in triple value: ",
408-
jp.getCurrentLocation().getLineNr(),
409-
jp.getCurrentLocation().getColumnNr());
408+
jp.currentLocation().getLineNr(),
409+
jp.currentLocation().getColumnNr());
410410
}
411411
predicate = parseValue(jp, fieldName + ":" + posName);
412412
} else if (OBJECT.equals(posName)) {
413413
if (object != null) {
414414
throw new QueryResultParseException(
415415
posName + " field encountered twice in triple value: ",
416-
jp.getCurrentLocation().getLineNr(),
417-
jp.getCurrentLocation().getColumnNr());
416+
jp.currentLocation().getLineNr(),
417+
jp.currentLocation().getColumnNr());
418418
}
419419
object = parseValue(jp, fieldName + ":" + posName);
420420
} else if ("g".equals(posName)) {
421421
// silently ignore named graph field in Stardog dialect
422422
parseValue(jp, fieldName + ":" + posName);
423423
} else {
424424
throw new QueryResultParseException("Unexpected field name in triple value: " + posName,
425-
jp.getCurrentLocation().getLineNr(),
426-
jp.getCurrentLocation().getColumnNr());
425+
jp.currentLocation().getLineNr(),
426+
jp.currentLocation().getColumnNr());
427427
}
428428
}
429429

430430
if (subject instanceof Resource && predicate instanceof IRI && object != null) {
431431
return valueFactory.createTriple((Resource) subject, (IRI) predicate, object);
432432
} else {
433433
throw new QueryResultParseException("Incomplete or invalid triple value",
434-
jp.getCurrentLocation().getLineNr(),
435-
jp.getCurrentLocation().getColumnNr());
434+
jp.currentLocation().getLineNr(),
435+
jp.currentLocation().getColumnNr());
436436
}
437437
}
438438

439439
protected Triple parseTripleValue(JsonParser jp, String fieldName) throws IOException {
440-
throw new QueryResultParseException("Unexpected object as value", jp.getCurrentLocation().getLineNr(),
441-
jp.getCurrentLocation().getColumnNr());
440+
throw new QueryResultParseException("Unexpected object as value", jp.currentLocation().getLineNr(),
441+
jp.currentLocation().getColumnNr());
442442
}
443443

444444
protected boolean checkTripleType(JsonParser jp, String type) {
@@ -519,13 +519,13 @@ public Collection<RioSetting<?>> getSupportedSettings() {
519519
* @return A newly configured JsonFactory based on the currently enabled settings
520520
*/
521521
private JsonFactory configureNewJsonFactory() {
522-
final JsonFactoryBuilder builder = new JsonFactoryBuilder();
522+
var builder = JsonFactory.builder();
523523
// Disable features that may work for most JSON where the field names are
524524
// in limited supply,
525525
// but does not work for SPARQL/JSON where a wide range of URIs are used for
526526
// subjects and predicates
527-
builder.disable(JsonFactory.Feature.INTERN_FIELD_NAMES);
528-
builder.disable(JsonFactory.Feature.CANONICALIZE_FIELD_NAMES);
527+
builder.disable(TokenStreamFactory.Feature.INTERN_PROPERTY_NAMES);
528+
builder.disable(TokenStreamFactory.Feature.CANONICALIZE_PROPERTY_NAMES);
529529
builder.disable(StreamWriteFeature.AUTO_CLOSE_TARGET);
530530

531531
if (getParserConfig().isSet(JSONSettings.ALLOW_BACKSLASH_ESCAPING_ANY_CHARACTER)) {
@@ -553,7 +553,7 @@ private JsonFactory configureNewJsonFactory() {
553553
getParserConfig().get(JSONSettings.ALLOW_UNQUOTED_CONTROL_CHARS));
554554
}
555555
if (getParserConfig().isSet(JSONSettings.ALLOW_UNQUOTED_FIELD_NAMES)) {
556-
builder.configure(JsonReadFeature.ALLOW_UNQUOTED_FIELD_NAMES,
556+
builder.configure(JsonReadFeature.ALLOW_UNQUOTED_PROPERTY_NAMES,
557557
getParserConfig().get(JSONSettings.ALLOW_UNQUOTED_FIELD_NAMES));
558558
}
559559
if (getParserConfig().isSet(JSONSettings.ALLOW_YAML_COMMENTS)) {

0 commit comments

Comments
 (0)