0
# Utilities and Advanced Features
1
2
Jackson Core provides extensive utility classes and advanced features for specialized use cases including parser/generator delegation, filtering, buffer management, and async processing.
3
4
## Parser and Generator Delegation
5
6
### JsonParserDelegate
7
8
```java { .api }
9
public class JsonParserDelegate extends JsonParser {
10
protected JsonParser delegate;
11
12
public JsonParserDelegate(JsonParser d);
13
public JsonParser getDelegate();
14
public void setDelegate(JsonParser d);
15
16
// All JsonParser methods are delegated to the underlying parser
17
// Override specific methods to customize behavior
18
}
19
```
20
21
### JsonGeneratorDelegate
22
23
```java { .api }
24
public class JsonGeneratorDelegate extends JsonGenerator {
25
protected JsonGenerator delegate;
26
protected boolean delegateCopyMethods;
27
28
public JsonGeneratorDelegate(JsonGenerator d);
29
public JsonGeneratorDelegate(JsonGenerator d, boolean delegateCopyMethods);
30
31
public JsonGenerator getDelegate();
32
public void setDelegate(JsonGenerator d);
33
34
// All JsonGenerator methods are delegated to the underlying generator
35
// Override specific methods to customize behavior
36
}
37
```
38
39
### JsonGeneratorDecorator
40
41
```java { .api }
42
public interface JsonGeneratorDecorator {
43
JsonGenerator decorate(JsonFactory factory, JsonGenerator generator) throws IOException;
44
}
45
```
46
47
## Parser Sequencing
48
49
### JsonParserSequence
50
51
```java { .api }
52
public class JsonParserSequence extends JsonParserDelegate {
53
public static JsonParserSequence createFlattened(boolean checkForExistingToken, JsonParser first, JsonParser second);
54
public static JsonParserSequence createFlattened(boolean checkForExistingToken, JsonParser[] parsers);
55
56
public void addFlattenedActiveParsers(List<JsonParser> listToAddIn);
57
public int containedParsersCount();
58
59
@Override
60
public void close() throws IOException;
61
@Override
62
public JsonToken nextToken() throws IOException;
63
}
64
```
65
66
## Filtering
67
68
### TokenFilter
69
70
```java { .api }
71
public abstract class TokenFilter {
72
public static final TokenFilter INCLUDE_ALL;
73
74
public abstract TokenFilter includeElement(int index);
75
public abstract TokenFilter includeProperty(String name);
76
public abstract boolean includeValue(JsonParser p) throws IOException;
77
public abstract boolean includeRootValue(int index);
78
79
public boolean _includeScalar();
80
protected boolean _includeScalar(JsonParser p) throws IOException;
81
}
82
```
83
84
### JsonPointerBasedFilter
85
86
```java { .api }
87
public class JsonPointerBasedFilter extends TokenFilter {
88
protected final JsonPointer _pathToMatch;
89
90
public JsonPointerBasedFilter(String pathAsString);
91
public JsonPointerBasedFilter(JsonPointer match);
92
93
@Override
94
public TokenFilter includeElement(int index);
95
@Override
96
public TokenFilter includeProperty(String name);
97
@Override
98
public boolean includeValue(JsonParser p) throws IOException;
99
100
@Override
101
public String toString();
102
}
103
```
104
105
### FilteringParserDelegate
106
107
```java { .api }
108
public class FilteringParserDelegate extends JsonParserDelegate {
109
public enum Inclusion {
110
INCLUDE_ALL_AND_PATH,
111
INCLUDE_NON_NULL,
112
ONLY_INCLUDE_ALL
113
}
114
115
protected TokenFilter rootFilter;
116
protected boolean _allowMultipleMatches;
117
protected boolean _includePath;
118
protected boolean _includeImmediateParent;
119
120
public FilteringParserDelegate(JsonParser p, TokenFilter f, boolean includePath, boolean allowMultipleMatches);
121
public FilteringParserDelegate(JsonParser p, TokenFilter f, Inclusion inclusion, boolean allowMultipleMatches);
122
123
public TokenFilter getFilter();
124
public int getMatchCount();
125
126
@Override
127
public JsonToken nextToken() throws IOException;
128
@Override
129
public JsonToken getCurrentToken();
130
@Override
131
public String getCurrentName() throws IOException;
132
}
133
```
134
135
### FilteringGeneratorDelegate
136
137
```java { .api }
138
public class FilteringGeneratorDelegate extends JsonGeneratorDelegate {
139
protected TokenFilter rootFilter;
140
protected boolean _allowMultipleMatches;
141
protected boolean _includePath;
142
protected boolean _includeImmediateParent;
143
144
public FilteringGeneratorDelegate(JsonGenerator d, TokenFilter f, boolean includePath, boolean allowMultipleMatches);
145
public FilteringGeneratorDelegate(JsonGenerator d, TokenFilter f, Inclusion inclusion, boolean allowMultipleMatches);
146
147
public TokenFilter getFilter();
148
public int getMatchCount();
149
150
// Override write methods to apply filtering
151
}
152
```
153
154
## Buffer Management
155
156
### BufferRecycler
157
158
```java { .api }
159
public class BufferRecycler {
160
public enum BufferType {
161
BYTE_READ_IO_BUFFER(0, 8000),
162
BYTE_WRITE_ENCODING_BUFFER(1, 8000),
163
BYTE_WRITE_CONCAT_BUFFER(2, 2000),
164
CHAR_TOKEN_BUFFER(3, 2000),
165
CHAR_CONCAT_BUFFER(4, 2000),
166
CHAR_TEXT_BUFFER(5, 200),
167
CHAR_NAME_COPY_BUFFER(6, 200);
168
169
public int getId();
170
public int getDefaultSize();
171
}
172
173
public byte[] allocByteBuffer(BufferType type);
174
public byte[] allocByteBuffer(BufferType type, int minSize);
175
public void releaseByteBuffer(BufferType type, byte[] buffer);
176
177
public char[] allocCharBuffer(BufferType type);
178
public char[] allocCharBuffer(BufferType type, int minSize);
179
public void releaseCharBuffer(BufferType type, char[] buffer);
180
}
181
```
182
183
### BufferRecyclers
184
185
```java { .api }
186
public class BufferRecyclers {
187
public static BufferRecycler getBufferRecycler();
188
public static RecyclerPool<BufferRecycler> getBufferRecyclerPool();
189
public static void releaseBuffers();
190
191
public static void setBufferRecyclerPool(RecyclerPool<BufferRecycler> pool);
192
}
193
```
194
195
### RecyclerPool
196
197
```java { .api }
198
public interface RecyclerPool<T> {
199
T acquirePooled();
200
void releasePooled(T pooled);
201
202
public static class BoundedPoolBase<P> implements RecyclerPool<P> {
203
protected final int _maxPooled;
204
public BoundedPoolBase(int poolSize);
205
public int capacity();
206
}
207
208
public static final class ThreadLocalPool<P> extends BoundedPoolBase<P> {
209
public ThreadLocalPool(int poolSize);
210
public ThreadLocalPool(int poolSize, Function<RecyclerPool<P>, P> creator);
211
}
212
213
public static final class LockFreePool<P> extends BoundedPoolBase<P> {
214
public LockFreePool(int poolSize);
215
public LockFreePool(int poolSize, Function<RecyclerPool<P>, P> creator);
216
}
217
218
public static final class ConcurrentDequePool<P> extends BoundedPoolBase<P> {
219
public ConcurrentDequePool(int poolSize);
220
public ConcurrentDequePool(int poolSize, Function<RecyclerPool<P>, P> creator);
221
}
222
223
public static final class NonRecyclingPool<P> implements RecyclerPool<P> {
224
public NonRecyclingPool();
225
public NonRecyclingPool(Function<RecyclerPool<P>, P> creator);
226
}
227
}
228
```
229
230
## Text Processing
231
232
### TextBuffer
233
234
```java { .api }
235
public final class TextBuffer {
236
public TextBuffer(BufferRecycler allocator);
237
public TextBuffer(BufferRecycler allocator, int initialSize);
238
239
public void releaseBuffers();
240
public void resetWithEmpty();
241
public void resetWith(char c);
242
public void resetWithShared(char[] buf, int offset, int len);
243
public void resetWithCopy(char[] buf, int offset, int len);
244
public void resetWithCopy(String text, int start, int len);
245
public void resetWithString(String value);
246
247
public char[] getTextBuffer();
248
public int getTextOffset();
249
public int size();
250
public String contentsAsString();
251
public char[] contentsAsArray();
252
public BigDecimal contentsAsDecimal() throws NumberFormatException;
253
public double contentsAsDouble() throws NumberFormatException;
254
public int contentsAsInt(boolean neg) throws NumberFormatException;
255
public long contentsAsLong(boolean neg) throws NumberFormatException;
256
257
public char[] getCurrentSegment();
258
public char[] emptyAndGetCurrentSegment();
259
public int getCurrentSegmentSize();
260
public void setCurrentLength(int len);
261
public char[] finishCurrentSegment();
262
public char[] expandCurrentSegment();
263
public char[] expandCurrentSegment(int minSize);
264
265
public void append(char c);
266
public void append(char[] c, int start, int len);
267
public void append(String str, int offset, int len);
268
public void appendString(String str);
269
270
public String toString();
271
}
272
```
273
274
### ByteArrayBuilder
275
276
```java { .api }
277
public final class ByteArrayBuilder extends OutputStream {
278
public ByteArrayBuilder();
279
public ByteArrayBuilder(BufferRecycler br);
280
public ByteArrayBuilder(BufferRecycler br, int firstBlockSize);
281
public ByteArrayBuilder(int firstBlockSize);
282
283
public void reset();
284
public void release();
285
public int size();
286
287
public byte[] toByteArray();
288
public byte[] resetAndGetFirstSegment();
289
public void write(byte[] b);
290
public void write(byte[] b, int off, int len);
291
public void write(int b);
292
public void writeBytes(byte[] b, int off, int len);
293
294
public void close();
295
public void flush();
296
297
public String toString();
298
}
299
```
300
301
## Async Processing
302
303
### NonBlockingInputFeeder
304
305
```java { .api }
306
public interface NonBlockingInputFeeder {
307
boolean needMoreInput();
308
void feedInput(byte[] buf, int start, int end) throws IOException;
309
void endOfInput();
310
}
311
```
312
313
### ByteArrayFeeder
314
315
```java { .api }
316
public interface ByteArrayFeeder extends NonBlockingInputFeeder {
317
void feedInput(byte[] buf, int start, int end) throws IOException;
318
}
319
```
320
321
### ByteBufferFeeder
322
323
```java { .api }
324
public interface ByteBufferFeeder extends NonBlockingInputFeeder {
325
void feedInput(ByteBuffer buffer) throws IOException;
326
}
327
```
328
329
## Pretty Printing
330
331
### Separators
332
333
```java { .api }
334
public class Separators implements Serializable {
335
public static final Separators DEFAULT;
336
337
public Separators();
338
public Separators(char objectFieldValueSeparator, char objectEntrySeparator, char arrayValueSeparator);
339
340
public Separators withObjectFieldValueSeparator(char sep);
341
public Separators withObjectEntrySeparator(char sep);
342
public Separators withArrayValueSeparator(char sep);
343
344
public char getObjectFieldValueSeparator();
345
public char getObjectEntrySeparator();
346
public char getArrayValueSeparator();
347
}
348
```
349
350
### MinimalPrettyPrinter
351
352
```java { .api }
353
public class MinimalPrettyPrinter implements PrettyPrinter, Serializable {
354
public MinimalPrettyPrinter();
355
public MinimalPrettyPrinter(String rootSeparator);
356
357
public void setRootValueSeparator(String sep);
358
359
@Override
360
public void writeRootValueSeparator(JsonGenerator gen) throws IOException;
361
@Override
362
public void writeStartObject(JsonGenerator gen) throws IOException;
363
@Override
364
public void writeEndObject(JsonGenerator gen, int nrOfEntries) throws IOException;
365
@Override
366
public void writeObjectEntryValueSeparator(JsonGenerator gen) throws IOException;
367
@Override
368
public void writeObjectFieldValueSeparator(JsonGenerator gen) throws IOException;
369
@Override
370
public void writeStartArray(JsonGenerator gen) throws IOException;
371
@Override
372
public void writeEndArray(JsonGenerator gen, int nrOfValues) throws IOException;
373
@Override
374
public void writeArrayValueSeparator(JsonGenerator gen) throws IOException;
375
@Override
376
public void beforeArrayValues(JsonGenerator gen) throws IOException;
377
@Override
378
public void beforeObjectEntries(JsonGenerator gen) throws IOException;
379
}
380
```
381
382
## Usage Examples
383
384
### Custom Parser with Logging
385
386
```java
387
public class LoggingParserDelegate extends JsonParserDelegate {
388
private static final Logger logger = LoggerFactory.getLogger(LoggingParserDelegate.class);
389
390
public LoggingParserDelegate(JsonParser delegate) {
391
super(delegate);
392
}
393
394
@Override
395
public JsonToken nextToken() throws IOException {
396
JsonToken token = super.nextToken();
397
if (token != null) {
398
logger.debug("Token: {} at {}", token, getCurrentLocation());
399
}
400
return token;
401
}
402
403
@Override
404
public String getText() throws IOException {
405
String text = super.getText();
406
logger.debug("Text value: '{}'", text);
407
return text;
408
}
409
}
410
411
// Usage
412
JsonParser parser = new LoggingParserDelegate(factory.createParser(input));
413
```
414
415
### JSON Path Filtering
416
417
```java
418
// Parse only specific paths from large JSON
419
JsonPointer pathToExtract = JsonPointer.compile("/users/0/profile/name");
420
TokenFilter filter = new JsonPointerBasedFilter(pathToExtract);
421
422
JsonParser parser = new FilteringParserDelegate(
423
factory.createParser(largeJsonInput),
424
filter,
425
false, // don't include path
426
false // single match only
427
);
428
429
while (parser.nextToken() != null) {
430
if (parser.getCurrentToken() == JsonToken.VALUE_STRING) {
431
String extractedName = parser.getText();
432
System.out.println("Found name: " + extractedName);
433
break;
434
}
435
}
436
```
437
438
### Custom Buffer Pool
439
440
```java
441
// Custom buffer recycling strategy
442
RecyclerPool<BufferRecycler> customPool = new RecyclerPool.ThreadLocalPool<>(10);
443
BufferRecyclers.setBufferRecyclerPool(customPool);
444
445
// Or disable recycling entirely
446
BufferRecyclers.setBufferRecyclerPool(new RecyclerPool.NonRecyclingPool<>());
447
```
448
449
### Non-blocking JSON Parsing
450
451
```java
452
JsonFactory factory = new JsonFactory();
453
JsonParser parser = factory.createNonBlockingByteArrayParser();
454
ByteArrayFeeder feeder = (ByteArrayFeeder) parser.getNonBlockingInputFeeder();
455
456
// Feed data in chunks
457
byte[] chunk1 = "{\"name\":\"John\",".getBytes();
458
byte[] chunk2 = "\"age\":30}".getBytes();
459
460
feeder.feedInput(chunk1, 0, chunk1.length);
461
JsonToken token;
462
while ((token = parser.nextToken()) == JsonToken.NOT_AVAILABLE) {
463
// Need more input
464
}
465
466
feeder.feedInput(chunk2, 0, chunk2.length);
467
feeder.endOfInput();
468
469
// Continue parsing
470
while ((token = parser.nextToken()) != null) {
471
// Process tokens
472
}
473
```
474
475
### Memory-Efficient Large JSON Processing
476
477
```java
478
public void processLargeJsonArray(InputStream input, Consumer<JsonNode> processor) throws IOException {
479
JsonFactory factory = JsonFactory.builder()
480
.disable(JsonFactory.Feature.INTERN_FIELD_NAMES) // Save memory
481
.disable(StreamReadFeature.INCLUDE_SOURCE_IN_LOCATION) // Save memory
482
.build();
483
484
try (JsonParser parser = factory.createParser(input)) {
485
parser.nextToken(); // START_ARRAY
486
487
while (parser.nextToken() == JsonToken.START_OBJECT) {
488
JsonNode node = parser.readValueAsTree();
489
processor.accept(node);
490
491
// Node is automatically garbage collected after processing
492
}
493
}
494
}
495
```