blob: eb93746596d9e50869307b6d2ad2fd9b79ff35d6 [file] [log] [blame]
Tatu Salorantaf15531c2011-12-22 23:00:40 -08001/* Jackson JSON-processor.
2 *
3 * Copyright (c) 2007- Tatu Saloranta, tatu.saloranta@iki.fi
Tatu Salorantaf15531c2011-12-22 23:00:40 -08004 */
5package com.fasterxml.jackson.core;
6
7import java.io.*;
8import java.lang.ref.SoftReference;
9import java.net.URL;
10
11import com.fasterxml.jackson.core.format.InputAccessor;
12import com.fasterxml.jackson.core.format.MatchStrength;
13import com.fasterxml.jackson.core.io.*;
Tatu07351902012-01-19 13:12:13 -080014import com.fasterxml.jackson.core.json.*;
Tatu Saloranta81fb43c2017-05-17 18:25:34 -070015import com.fasterxml.jackson.core.json.async.NonBlockingJsonParser;
Cowtowncoder3a00c862015-02-04 22:30:30 -080016import com.fasterxml.jackson.core.sym.ByteQuadsCanonicalizer;
Tatu Salorantaf15531c2011-12-22 23:00:40 -080017import com.fasterxml.jackson.core.sym.CharsToNameCanonicalizer;
18import com.fasterxml.jackson.core.util.BufferRecycler;
Tatu Salorantae6dfc692012-09-28 15:34:05 -070019import com.fasterxml.jackson.core.util.DefaultPrettyPrinter;
Tatu Salorantaf15531c2011-12-22 23:00:40 -080020
21/**
22 * The main factory class of Jackson package, used to configure and
23 * construct reader (aka parser, {@link JsonParser})
24 * and writer (aka generator, {@link JsonGenerator})
25 * instances.
26 *<p>
27 * Factory instances are thread-safe and reusable after configuration
28 * (if any). Typically applications and services use only a single
29 * globally shared factory instance, unless they need differently
30 * configured factories. Factory reuse is important if efficiency matters;
31 * most recycling of expensive construct is done on per-factory basis.
32 *<p>
33 * Creation of a factory instance is a light-weight operation,
34 * and since there is no need for pluggable alternative implementations
35 * (as there is no "standard" JSON processor API to implement),
36 * the default constructor is used for constructing factory
37 * instances.
38 *
39 * @author Tatu Saloranta
40 */
Tatu Salorantae92d04f2013-07-24 22:58:08 -070041@SuppressWarnings("resource")
Tatu Saloranta95f76a42012-10-05 13:04:23 -070042public class JsonFactory
43 implements Versioned,
44 java.io.Serializable // since 2.1 (for Android, mostly)
Tatu Salorantaf15531c2011-12-22 23:00:40 -080045{
Tatu Salorantadccffbe2015-02-05 21:17:57 -080046 private static final long serialVersionUID = 1; // since 2.6.0
Tatu Saloranta95f76a42012-10-05 13:04:23 -070047
Tatu Saloranta7b796a82013-04-27 10:18:30 -070048 /*
49 /**********************************************************
50 /* Helper types
51 /**********************************************************
Tatu Salorantaf15531c2011-12-22 23:00:40 -080052 */
Tatu Salorantae92d04f2013-07-24 22:58:08 -070053
Tatu07351902012-01-19 13:12:13 -080054 /**
55 * Enumeration that defines all on/off features that can only be
56 * changed for {@link JsonFactory}.
57 */
58 public enum Feature {
59
60 // // // Symbol handling (interning etc)
61
62 /**
63 * Feature that determines whether JSON object field names are
64 * to be canonicalized using {@link String#intern} or not:
65 * if enabled, all field names will be intern()ed (and caller
66 * can count on this being true for all such names); if disabled,
67 * no intern()ing is done. There may still be basic
68 * canonicalization (that is, same String will be used to represent
69 * all identical object property names for a single document).
70 *<p>
71 * Note: this setting only has effect if
72 * {@link #CANONICALIZE_FIELD_NAMES} is true -- otherwise no
73 * canonicalization of any sort is done.
74 *<p>
75 * This setting is enabled by default.
76 */
77 INTERN_FIELD_NAMES(true),
78
79 /**
80 * Feature that determines whether JSON object field names are
81 * to be canonicalized (details of how canonicalization is done
82 * then further specified by
83 * {@link #INTERN_FIELD_NAMES}).
84 *<p>
85 * This setting is enabled by default.
86 */
Tatu Saloranta383bc8f2014-05-24 00:47:07 -070087 CANONICALIZE_FIELD_NAMES(true),
88
89 /**
90 * Feature that determines what happens if we encounter a case in symbol
91 * handling where number of hash collisions exceeds a safety threshold
92 * -- which almost certainly means a denial-of-service attack via generated
93 * duplicate hash codes.
94 * If feature is enabled, an {@link IllegalStateException} is
95 * thrown to indicate the suspected denial-of-service attack; if disabled, processing continues but
96 * canonicalization (and thereby <code>intern()</code>ing) is disabled) as protective
97 * measure.
98 *<p>
99 * This setting is enabled by default.
100 *
101 * @since 2.4
102 */
103 FAIL_ON_SYMBOL_HASH_OVERFLOW(true),
Tatu07351902012-01-19 13:12:13 -0800104
Tatu Saloranta8891c0c2015-04-23 22:47:05 -0700105 /**
106 * Feature that determines whether we will use {@link BufferRecycler} with
107 * {@link ThreadLocal} and {@link SoftReference}, for efficient reuse of
108 * underlying input/output buffers.
109 * This usually makes sense on normal J2SE/J2EE server-side processing;
110 * but may not make sense on platforms where {@link SoftReference} handling
111 * is broken (like Android), or if there are retention issues due to
112 * {@link ThreadLocal} (see
113 * <a href="https://github.com/FasterXML/jackson-core/issues/189">Issue #189</a>
114 * for a possible case)
David Andrewseb41b102016-12-01 20:51:32 -0500115 *<p>
116 * This setting is enabled by default.
Tatu Saloranta8891c0c2015-04-23 22:47:05 -0700117 *
118 * @since 2.6
119 */
120 USE_THREAD_LOCAL_FOR_BUFFER_RECYCLING(true)
Tatu Salorantaf4255632017-04-17 22:03:51 -0700121
Tatu07351902012-01-19 13:12:13 -0800122 ;
123
124 /**
125 * Whether feature is enabled or disabled by default.
126 */
127 private final boolean _defaultState;
Tatu Salorantaf4255632017-04-17 22:03:51 -0700128
Tatu07351902012-01-19 13:12:13 -0800129 /**
130 * Method that calculates bit set (flags) of all features that
131 * are enabled by default.
132 */
Tatu Salorantae15b9a82014-01-24 21:01:04 -0800133 public static int collectDefaults() {
Tatu07351902012-01-19 13:12:13 -0800134 int flags = 0;
135 for (Feature f : values()) {
Tatu Salorantae15b9a82014-01-24 21:01:04 -0800136 if (f.enabledByDefault()) { flags |= f.getMask(); }
Tatu07351902012-01-19 13:12:13 -0800137 }
138 return flags;
139 }
140
Tatu Salorantae15b9a82014-01-24 21:01:04 -0800141 private Feature(boolean defaultState) { _defaultState = defaultState; }
Tatu07351902012-01-19 13:12:13 -0800142
143 public boolean enabledByDefault() { return _defaultState; }
Tatu07351902012-01-19 13:12:13 -0800144 public boolean enabledIn(int flags) { return (flags & getMask()) != 0; }
Tatu07351902012-01-19 13:12:13 -0800145 public int getMask() { return (1 << ordinal()); }
Tatu Saloranta7b796a82013-04-27 10:18:30 -0700146 }
147
148 /*
149 /**********************************************************
150 /* Constants
151 /**********************************************************
152 */
153
154 /**
155 * Name used to identify JSON format
156 * (and returned by {@link #getFormatName()}
157 */
158 public final static String FORMAT_NAME_JSON = "JSON";
159
160 /**
161 * Bitfield (set of flags) of all factory features that are enabled by default.
162 */
163 protected final static int DEFAULT_FACTORY_FEATURE_FLAGS = JsonFactory.Feature.collectDefaults();
164
165 /**
166 * Bitfield (set of flags) of all parser features that are enabled
167 * by default.
168 */
169 protected final static int DEFAULT_PARSER_FEATURE_FLAGS = JsonParser.Feature.collectDefaults();
170
171 /**
172 * Bitfield (set of flags) of all generator features that are enabled
173 * by default.
174 */
175 protected final static int DEFAULT_GENERATOR_FEATURE_FLAGS = JsonGenerator.Feature.collectDefaults();
176
177 private final static SerializableString DEFAULT_ROOT_VALUE_SEPARATOR = DefaultPrettyPrinter.DEFAULT_ROOT_VALUE_SEPARATOR;
178
Tatu Salorantaf15531c2011-12-22 23:00:40 -0800179 /*
180 /**********************************************************
181 /* Buffer, symbol table management
182 /**********************************************************
183 */
184
185 /**
Tatu Saloranta10c3ec82012-09-05 19:38:49 -0700186 * This <code>ThreadLocal</code> contains a {@link java.lang.ref.SoftReference}
Tatu Salorantaf15531c2011-12-22 23:00:40 -0800187 * to a {@link BufferRecycler} used to provide a low-cost
188 * buffer recycling between reader and writer instances.
189 */
190 final protected static ThreadLocal<SoftReference<BufferRecycler>> _recyclerRef
191 = new ThreadLocal<SoftReference<BufferRecycler>>();
192
193 /**
194 * Each factory comes equipped with a shared root symbol table.
195 * It should not be linked back to the original blueprint, to
196 * avoid contents from leaking between factories.
197 */
Tatu Saloranta95f76a42012-10-05 13:04:23 -0700198 protected final transient CharsToNameCanonicalizer _rootCharSymbols = CharsToNameCanonicalizer.createRoot();
Tatu Salorantaf15531c2011-12-22 23:00:40 -0800199
200 /**
201 * Alternative to the basic symbol table, some stream-based
202 * parsers use different name canonicalization method.
203 *<p>
204 * TODO: should clean up this; looks messy having 2 alternatives
205 * with not very clear differences.
Tatu Salorantadccffbe2015-02-05 21:17:57 -0800206 *
207 * @since 2.6.0
208 */
209 protected final transient ByteQuadsCanonicalizer _byteSymbolCanonicalizer = ByteQuadsCanonicalizer.createRoot();
210
Tatu Salorantaf15531c2011-12-22 23:00:40 -0800211 /*
212 /**********************************************************
213 /* Configuration
214 /**********************************************************
215 */
216
217 /**
218 * Object that implements conversion functionality between
219 * Java objects and JSON content. For base JsonFactory implementation
220 * usually not set by default, but can be explicitly set.
221 * Sub-classes (like @link org.codehaus.jackson.map.MappingJsonFactory}
222 * usually provide an implementation.
223 */
224 protected ObjectCodec _objectCodec;
225
226 /**
Tatu07351902012-01-19 13:12:13 -0800227 * Currently enabled factory features.
228 */
229 protected int _factoryFeatures = DEFAULT_FACTORY_FEATURE_FLAGS;
230
231 /**
Tatu Salorantaf15531c2011-12-22 23:00:40 -0800232 * Currently enabled parser features.
233 */
234 protected int _parserFeatures = DEFAULT_PARSER_FEATURE_FLAGS;
235
236 /**
237 * Currently enabled generator features.
238 */
239 protected int _generatorFeatures = DEFAULT_GENERATOR_FEATURE_FLAGS;
240
241 /**
242 * Definition of custom character escapes to use for generators created
243 * by this factory, if any. If null, standard data format specific
244 * escapes are used.
245 */
246 protected CharacterEscapes _characterEscapes;
247
248 /**
249 * Optional helper object that may decorate input sources, to do
250 * additional processing on input during parsing.
251 */
252 protected InputDecorator _inputDecorator;
253
254 /**
255 * Optional helper object that may decorate output object, to do
256 * additional processing on output during content generation.
257 */
258 protected OutputDecorator _outputDecorator;
Tatu Salorantae6dfc692012-09-28 15:34:05 -0700259
260 /**
261 * Separator used between root-level values, if any; null indicates
262 * "do not add separator".
263 * Default separator is a single space character.
264 *
265 * @since 2.1
266 */
267 protected SerializableString _rootValueSeparator = DEFAULT_ROOT_VALUE_SEPARATOR;
Tatu Salorantaf15531c2011-12-22 23:00:40 -0800268
269 /*
270 /**********************************************************
271 /* Construction
272 /**********************************************************
273 */
274
275 /**
276 * Default constructor used to create factory instances.
277 * Creation of a factory instance is a light-weight operation,
278 * but it is still a good idea to reuse limited number of
279 * factory instances (and quite often just a single instance):
280 * factories are used as context for storing some reused
281 * processing objects (such as symbol tables parsers use)
282 * and this reuse only works within context of a single
283 * factory instance.
284 */
Gonçalo Silva2bba5dd2014-01-25 17:06:21 +0000285 public JsonFactory() { this(null); }
Tatu Salorantaf15531c2011-12-22 23:00:40 -0800286
287 public JsonFactory(ObjectCodec oc) { _objectCodec = oc; }
288
Tatu Saloranta378ecdc2012-08-04 16:27:27 -0700289 /**
Tatu Saloranta7b796a82013-04-27 10:18:30 -0700290 * Constructor used when copy()ing a factory instance.
291 *
292 * @since 2.2.1
293 */
294 protected JsonFactory(JsonFactory src, ObjectCodec codec)
295 {
296 _objectCodec = null;
297 _factoryFeatures = src._factoryFeatures;
298 _parserFeatures = src._parserFeatures;
299 _generatorFeatures = src._generatorFeatures;
300 _characterEscapes = src._characterEscapes;
301 _inputDecorator = src._inputDecorator;
302 _outputDecorator = src._outputDecorator;
303 _rootValueSeparator = src._rootValueSeparator;
304
305 /* 27-Apr-2013, tatu: How about symbol table; should we try to
306 * reuse shared symbol tables? Could be more efficient that way;
307 * although can slightly add to concurrency overhead.
308 */
309 }
310
311 /**
Tatu Saloranta378ecdc2012-08-04 16:27:27 -0700312 * Method for constructing a new {@link JsonFactory} that has
313 * the same settings as this instance, but is otherwise
314 * independent (i.e. nothing is actually shared, symbol tables
315 * are separate).
316 * Note that {@link ObjectCodec} reference is not copied but is
317 * set to null; caller typically needs to set it after calling
Tatu Saloranta7b796a82013-04-27 10:18:30 -0700318 * this method. Reason for this is that the codec is used for
319 * callbacks, and assumption is that there is strict 1-to-1
320 * mapping between codec, factory. Caller has to, then, explicitly
321 * set codec after making the copy.
Tatu Saloranta378ecdc2012-08-04 16:27:27 -0700322 *
323 * @since 2.1
324 */
325 public JsonFactory copy()
326 {
327 _checkInvalidCopy(JsonFactory.class);
Tatu Saloranta7b796a82013-04-27 10:18:30 -0700328 // as per above, do clear ObjectCodec
329 return new JsonFactory(this, null);
Tatu Saloranta378ecdc2012-08-04 16:27:27 -0700330 }
Tatu Saloranta7b796a82013-04-27 10:18:30 -0700331
Tatu Saloranta378ecdc2012-08-04 16:27:27 -0700332 /**
333 * @since 2.1
334 * @param exp
335 */
336 protected void _checkInvalidCopy(Class<?> exp)
337 {
338 if (getClass() != exp) {
339 throw new IllegalStateException("Failed copy(): "+getClass().getName()
340 +" (version: "+version()+") does not override copy(); it has to");
341 }
342 }
Tatu Saloranta95f76a42012-10-05 13:04:23 -0700343
344 /*
345 /**********************************************************
346 /* Serializable overrides
347 /**********************************************************
348 */
349
350 /**
351 * Method that we need to override to actually make restoration go
352 * through constructors etc.
353 * Also: must be overridden by sub-classes as well.
354 */
355 protected Object readResolve() {
Tatu Salorantaf7741c52013-04-27 11:06:30 -0700356 return new JsonFactory(this, _objectCodec);
Tatu Saloranta95f76a42012-10-05 13:04:23 -0700357 }
Tatu Salorantaa9e5c9f2013-08-28 19:39:59 -0700358
359 /*
360 /**********************************************************
361 /* Capability introspection
362 /**********************************************************
363 */
364
365 /**
366 * Introspection method that higher-level functionality may call
367 * to see whether underlying data format requires a stable ordering
368 * of object properties or not.
369 * This is usually used for determining
370 * whether to force a stable ordering (like alphabetic ordering by name)
371 * if no ordering if explicitly specified.
372 *<p>
373 * Default implementation returns <code>false</code> as JSON does NOT
374 * require stable ordering. Formats that require ordering include positional
375 * textual formats like <code>CSV</code>, and schema-based binary formats
376 * like <code>Avro</code>.
377 *
378 * @since 2.3
379 */
Tatu475a99b2014-04-22 14:32:50 -0700380 public boolean requiresPropertyOrdering() { return false; }
Tatu Salorantab8835442013-09-14 12:12:57 -0700381
382 /**
383 * Introspection method that higher-level functionality may call
384 * to see whether underlying data format can read and write binary
385 * data natively; that is, embeded it as-is without using encodings
386 * such as Base64.
387 *<p>
388 * Default implementation returns <code>false</code> as JSON does not
389 * support native access: all binary content must use Base64 encoding.
390 * Most binary formats (like Smile and Avro) support native binary content.
391 *
392 * @since 2.3
393 */
Tatu475a99b2014-04-22 14:32:50 -0700394 public boolean canHandleBinaryNatively() { return false; }
Tatu Salorantab8835442013-09-14 12:12:57 -0700395
Tatu475a99b2014-04-22 14:32:50 -0700396 /**
397 * Introspection method that can be used by base factory to check
398 * whether access using <code>char[]</code> is something that actual
399 * parser implementations can take advantage of, over having to
400 * use {@link java.io.Reader}. Sub-types are expected to override
401 * definition; default implementation (suitable for JSON) alleges
402 * that optimization are possible; and thereby is likely to try
403 * to access {@link java.lang.String} content by first copying it into
404 * recyclable intermediate buffer.
405 *
406 * @since 2.4
407 */
408 public boolean canUseCharArrays() { return true; }
Cowtowncoder2e262b92015-05-27 17:32:17 -0700409
410 /**
Tatu Saloranta78b01182017-05-10 21:02:18 -0700411 * Introspection method that can be used to check whether this
412 * factory can create non-blocking parsers: parsers that do not
413 * use blocking I/O abstractions but instead use a
414 * {@link com.fasterxml.jackson.core.async.NonBlockingInputFeeder}.
415 *
416 * @since 2.9
417 */
418 public boolean canParseAsync() { return false; }
419
420 /**
Cowtowncoder2e262b92015-05-27 17:32:17 -0700421 * Method for accessing kind of {@link FormatFeature} that a parser
422 * {@link JsonParser} produced by this factory would accept, if any;
423 * <code>null</code> returned if none.
424 *
425 * @since 2.6
426 */
427 public Class<? extends FormatFeature> getFormatReadFeatureType() {
428 return null;
429 }
430
431 /**
432 * Method for accessing kind of {@link FormatFeature} that a parser
433 * {@link JsonGenerator} produced by this factory would accept, if any;
434 * <code>null</code> returned if none.
435 *
436 * @since 2.6
437 */
438 public Class<? extends FormatFeature> getFormatWriteFeatureType() {
439 return null;
440 }
Tatu Salorantaf15531c2011-12-22 23:00:40 -0800441 /*
442 /**********************************************************
Cowtowncoder2e262b92015-05-27 17:32:17 -0700443 /* Format detection functionality
Tatu Salorantaf15531c2011-12-22 23:00:40 -0800444 /**********************************************************
445 */
446
447 /**
Tatu Saloranta1bdf0262012-08-24 14:43:17 -0700448 * Method that can be used to quickly check whether given schema
449 * is something that parsers and/or generators constructed by this
450 * factory could use. Note that this means possible use, at the level
451 * of data format (i.e. schema is for same data format as parsers and
452 * generators this factory constructs); individual schema instances
453 * may have further usage restrictions.
454 *
455 * @since 2.1
456 */
457 public boolean canUseSchema(FormatSchema schema) {
Tatu Saloranta244ddd12016-05-14 15:11:04 -0700458 if (schema == null){
459 return false;
460 }
Tatu Saloranta1bdf0262012-08-24 14:43:17 -0700461 String ourFormat = getFormatName();
462 return (ourFormat != null) && ourFormat.equals(schema.getSchemaType());
463 }
464
465 /**
Tatu Salorantaf15531c2011-12-22 23:00:40 -0800466 * Method that returns short textual id identifying format
467 * this factory supports.
468 *<p>
469 * Note: sub-classes should override this method; default
470 * implementation will return null for all sub-classes
471 */
472 public String getFormatName()
473 {
474 /* Somewhat nasty check: since we can't make this abstract
475 * (due to backwards compatibility concerns), need to prevent
476 * format name "leakage"
477 */
478 if (getClass() == JsonFactory.class) {
479 return FORMAT_NAME_JSON;
480 }
481 return null;
482 }
483
Cowtowncoder2e262b92015-05-27 17:32:17 -0700484 /**
485 * Convenience method for trying to determine whether input via given accessor
486 * is of format type supported by this factory.
487 */
Tatu Salorantaf15531c2011-12-22 23:00:40 -0800488 public MatchStrength hasFormat(InputAccessor acc) throws IOException
489 {
490 // since we can't keep this abstract, only implement for "vanilla" instance
491 if (getClass() == JsonFactory.class) {
492 return hasJSONFormat(acc);
493 }
494 return null;
495 }
496
Tatu Salorantaad2df5f2012-08-22 20:55:49 -0700497 /**
498 * Method that can be called to determine if a custom
499 * {@link ObjectCodec} is needed for binding data parsed
500 * using {@link JsonParser} constructed by this factory
501 * (which typically also implies the same for serialization
502 * with {@link JsonGenerator}).
503 *
504 * @return True if custom codec is needed with parsers and
505 * generators created by this factory; false if a general
506 * {@link ObjectCodec} is enough
507 *
508 * @since 2.1
509 */
510 public boolean requiresCustomCodec() {
511 return false;
512 }
513
514 /**
515 * Helper method that can be called to determine if content accessed
516 * using given accessor seems to be JSON content.
517 */
Tatu Salorantaf15531c2011-12-22 23:00:40 -0800518 protected MatchStrength hasJSONFormat(InputAccessor acc) throws IOException
519 {
520 return ByteSourceJsonBootstrapper.hasJSONFormat(acc);
Tatu Salorantaad2df5f2012-08-22 20:55:49 -0700521 }
522
Tatu Salorantaf15531c2011-12-22 23:00:40 -0800523 /*
524 /**********************************************************
525 /* Versioned
526 /**********************************************************
527 */
528
Tatu Saloranta68d79dd2013-01-10 21:13:46 -0800529 @Override
Tatu Salorantaf15531c2011-12-22 23:00:40 -0800530 public Version version() {
Tatu Saloranta68d79dd2013-01-10 21:13:46 -0800531 return PackageVersion.VERSION;
Tatu Salorantaf15531c2011-12-22 23:00:40 -0800532 }
533
534 /*
535 /**********************************************************
Tatu07351902012-01-19 13:12:13 -0800536 /* Configuration, factory features
Tatu Salorantaf15531c2011-12-22 23:00:40 -0800537 /**********************************************************
538 */
539
540 /**
541 * Method for enabling or disabling specified parser feature
542 * (check {@link JsonParser.Feature} for list of features)
543 */
Tatu07351902012-01-19 13:12:13 -0800544 public final JsonFactory configure(JsonFactory.Feature f, boolean state) {
545 return state ? enable(f) : disable(f);
546 }
547
548 /**
549 * Method for enabling specified parser feature
550 * (check {@link JsonFactory.Feature} for list of features)
551 */
552 public JsonFactory enable(JsonFactory.Feature f) {
553 _factoryFeatures |= f.getMask();
Tatu Salorantaf15531c2011-12-22 23:00:40 -0800554 return this;
555 }
556
557 /**
Tatu07351902012-01-19 13:12:13 -0800558 * Method for disabling specified parser features
559 * (check {@link JsonFactory.Feature} for list of features)
560 */
561 public JsonFactory disable(JsonFactory.Feature f) {
562 _factoryFeatures &= ~f.getMask();
563 return this;
564 }
565
566 /**
567 * Checked whether specified parser feature is enabled.
568 */
569 public final boolean isEnabled(JsonFactory.Feature f) {
570 return (_factoryFeatures & f.getMask()) != 0;
571 }
572
573 /*
574 /**********************************************************
575 /* Configuration, parser configuration
576 /**********************************************************
577 */
578
579 /**
580 * Method for enabling or disabling specified parser feature
581 * (check {@link JsonParser.Feature} for list of features)
582 */
583 public final JsonFactory configure(JsonParser.Feature f, boolean state) {
584 return state ? enable(f) : disable(f);
585 }
586
587 /**
Tatu Salorantaf15531c2011-12-22 23:00:40 -0800588 * Method for enabling specified parser feature
589 * (check {@link JsonParser.Feature} for list of features)
590 */
591 public JsonFactory enable(JsonParser.Feature f) {
592 _parserFeatures |= f.getMask();
593 return this;
594 }
595
596 /**
597 * Method for disabling specified parser features
598 * (check {@link JsonParser.Feature} for list of features)
599 */
600 public JsonFactory disable(JsonParser.Feature f) {
601 _parserFeatures &= ~f.getMask();
602 return this;
603 }
604
605 /**
606 * Checked whether specified parser feature is enabled.
607 */
608 public final boolean isEnabled(JsonParser.Feature f) {
609 return (_parserFeatures & f.getMask()) != 0;
610 }
611
612 /**
613 * Method for getting currently configured input decorator (if any;
614 * there is no default decorator).
615 */
616 public InputDecorator getInputDecorator() {
617 return _inputDecorator;
618 }
619
620 /**
621 * Method for overriding currently configured input decorator
622 */
623 public JsonFactory setInputDecorator(InputDecorator d) {
624 _inputDecorator = d;
625 return this;
626 }
627
628 /*
629 /**********************************************************
630 /* Configuration, generator settings
631 /**********************************************************
632 */
633
634 /**
635 * Method for enabling or disabling specified generator feature
636 * (check {@link JsonGenerator.Feature} for list of features)
637 */
638 public final JsonFactory configure(JsonGenerator.Feature f, boolean state) {
Tatu07351902012-01-19 13:12:13 -0800639 return state ? enable(f) : disable(f);
Tatu Salorantaf15531c2011-12-22 23:00:40 -0800640 }
641
642
643 /**
644 * Method for enabling specified generator features
645 * (check {@link JsonGenerator.Feature} for list of features)
646 */
647 public JsonFactory enable(JsonGenerator.Feature f) {
648 _generatorFeatures |= f.getMask();
649 return this;
650 }
651
652 /**
653 * Method for disabling specified generator feature
654 * (check {@link JsonGenerator.Feature} for list of features)
655 */
656 public JsonFactory disable(JsonGenerator.Feature f) {
657 _generatorFeatures &= ~f.getMask();
658 return this;
659 }
660
661 /**
662 * Check whether specified generator feature is enabled.
663 */
664 public final boolean isEnabled(JsonGenerator.Feature f) {
665 return (_generatorFeatures & f.getMask()) != 0;
666 }
667
668 /**
669 * Method for accessing custom escapes factory uses for {@link JsonGenerator}s
670 * it creates.
671 */
Tatu Saloranta32e4e912014-01-26 19:59:28 -0800672 public CharacterEscapes getCharacterEscapes() { return _characterEscapes; }
Tatu Salorantaf15531c2011-12-22 23:00:40 -0800673
674 /**
675 * Method for defining custom escapes factory uses for {@link JsonGenerator}s
676 * it creates.
677 */
678 public JsonFactory setCharacterEscapes(CharacterEscapes esc) {
679 _characterEscapes = esc;
680 return this;
681 }
682
683 /**
684 * Method for getting currently configured output decorator (if any;
685 * there is no default decorator).
686 */
687 public OutputDecorator getOutputDecorator() {
688 return _outputDecorator;
689 }
690
691 /**
692 * Method for overriding currently configured output decorator
693 */
694 public JsonFactory setOutputDecorator(OutputDecorator d) {
695 _outputDecorator = d;
696 return this;
697 }
Tatu Salorantae6dfc692012-09-28 15:34:05 -0700698
699 /**
700 * Method that allows overriding String used for separating root-level
701 * JSON values (default is single space character)
702 *
703 * @param sep Separator to use, if any; null means that no separator is
704 * automatically added
705 *
706 * @since 2.1
707 */
708 public JsonFactory setRootValueSeparator(String sep) {
709 _rootValueSeparator = (sep == null) ? null : new SerializedString(sep);
710 return this;
711 }
712
713 /**
714 * @since 2.1
715 */
716 public String getRootValueSeparator() {
717 return (_rootValueSeparator == null) ? null : _rootValueSeparator.getValue();
718 }
Tatu Salorantaf15531c2011-12-22 23:00:40 -0800719
720 /*
721 /**********************************************************
722 /* Configuration, other
723 /**********************************************************
724 */
725
726 /**
727 * Method for associating a {@link ObjectCodec} (typically
Tatu Salorantad77350e2011-12-22 23:13:13 -0800728 * a <code>com.fasterxml.jackson.databind.ObjectMapper</code>)
729 * with this factory (and more importantly, parsers and generators
Tatu Salorantaf15531c2011-12-22 23:00:40 -0800730 * it constructs). This is needed to use data-binding methods
731 * of {@link JsonParser} and {@link JsonGenerator} instances.
732 */
733 public JsonFactory setCodec(ObjectCodec oc) {
734 _objectCodec = oc;
735 return this;
736 }
737
738 public ObjectCodec getCodec() { return _objectCodec; }
739
740 /*
741 /**********************************************************
Tatu Saloranta81fb43c2017-05-17 18:25:34 -0700742 /* Parser factories, traditional (blocking) I/O sources
Tatu Salorantaf15531c2011-12-22 23:00:40 -0800743 /**********************************************************
744 */
745
746 /**
747 * Method for constructing JSON parser instance to parse
Dmitry Spikhalskiy5590fcf2015-11-29 20:27:14 +0300748 * contents of specified file.
749 *
750 *<p>
751 * Encoding is auto-detected from contents according to JSON
752 * specification recommended mechanism. Json specification
753 * supports only UTF-8, UTF-16 and UTF-32 as valid encodings,
754 * so auto-detection implemented only for this charsets.
755 * For other charsets use {@link #createParser(java.io.Reader)}.
756 *
Tatu Salorantaf15531c2011-12-22 23:00:40 -0800757 *<p>
758 * Underlying input stream (needed for reading contents)
759 * will be <b>owned</b> (and managed, i.e. closed as need be) by
760 * the parser, since caller has no access to it.
761 *
762 * @param f File that contains JSON content to parse
Tatu Salorantafeaabd12012-07-22 23:03:41 -0700763 *
764 * @since 2.1
765 */
Tatu Saloranta32e4e912014-01-26 19:59:28 -0800766 public JsonParser createParser(File f) throws IOException, JsonParseException {
Tatu Salorantaf15531c2011-12-22 23:00:40 -0800767 // true, since we create InputStream from File
768 IOContext ctxt = _createContext(f, true);
769 InputStream in = new FileInputStream(f);
Tatu Saloranta896000f2014-04-19 12:53:40 -0700770 return _createParser(_decorate(in, ctxt), ctxt);
Tatu Salorantaf15531c2011-12-22 23:00:40 -0800771 }
772
773 /**
774 * Method for constructing JSON parser instance to parse
775 * contents of resource reference by given URL.
Dmitry Spikhalskiy5590fcf2015-11-29 20:27:14 +0300776 *
777 *<p>
778 * Encoding is auto-detected from contents according to JSON
779 * specification recommended mechanism. Json specification
780 * supports only UTF-8, UTF-16 and UTF-32 as valid encodings,
781 * so auto-detection implemented only for this charsets.
782 * For other charsets use {@link #createParser(java.io.Reader)}.
783 *
Tatu Salorantaf15531c2011-12-22 23:00:40 -0800784 *<p>
785 * Underlying input stream (needed for reading contents)
786 * will be <b>owned</b> (and managed, i.e. closed as need be) by
787 * the parser, since caller has no access to it.
788 *
789 * @param url URL pointing to resource that contains JSON content to parse
Tatu Saloranta68194922012-11-15 20:34:29 -0800790 *
791 * @since 2.1
Tatu Salorantaf15531c2011-12-22 23:00:40 -0800792 */
Tatu Saloranta32e4e912014-01-26 19:59:28 -0800793 public JsonParser createParser(URL url) throws IOException, JsonParseException {
Tatu Salorantaf15531c2011-12-22 23:00:40 -0800794 // true, since we create InputStream from URL
795 IOContext ctxt = _createContext(url, true);
796 InputStream in = _optimizedStreamFromURL(url);
Tatu Saloranta896000f2014-04-19 12:53:40 -0700797 return _createParser(_decorate(in, ctxt), ctxt);
Tatu Salorantaf15531c2011-12-22 23:00:40 -0800798 }
799
800 /**
801 * Method for constructing JSON parser instance to parse
802 * the contents accessed via specified input stream.
803 *<p>
804 * The input stream will <b>not be owned</b> by
805 * the parser, it will still be managed (i.e. closed if
806 * end-of-stream is reacher, or parser close method called)
807 * if (and only if) {@link com.fasterxml.jackson.core.JsonParser.Feature#AUTO_CLOSE_SOURCE}
808 * is enabled.
809 *<p>
Dmitry Spikhalskiy5590fcf2015-11-29 20:27:14 +0300810 *
Tatu Salorantaf15531c2011-12-22 23:00:40 -0800811 * Note: no encoding argument is taken since it can always be
Dmitry Spikhalskiy5590fcf2015-11-29 20:27:14 +0300812 * auto-detected as suggested by JSON RFC. Json specification
813 * supports only UTF-8, UTF-16 and UTF-32 as valid encodings,
814 * so auto-detection implemented only for this charsets.
815 * For other charsets use {@link #createParser(java.io.Reader)}.
Tatu Salorantaf15531c2011-12-22 23:00:40 -0800816 *
817 * @param in InputStream to use for reading JSON content to parse
Tatu Saloranta68194922012-11-15 20:34:29 -0800818 *
819 * @since 2.1
Tatu Salorantaf15531c2011-12-22 23:00:40 -0800820 */
Tatu Saloranta32e4e912014-01-26 19:59:28 -0800821 public JsonParser createParser(InputStream in) throws IOException, JsonParseException {
Tatu Salorantaf15531c2011-12-22 23:00:40 -0800822 IOContext ctxt = _createContext(in, false);
Tatu Saloranta896000f2014-04-19 12:53:40 -0700823 return _createParser(_decorate(in, ctxt), ctxt);
Tatu Salorantaf15531c2011-12-22 23:00:40 -0800824 }
Tatu Saloranta896000f2014-04-19 12:53:40 -0700825
Tatu Salorantaf15531c2011-12-22 23:00:40 -0800826 /**
827 * Method for constructing parser for parsing
828 * the contents accessed via specified Reader.
829 <p>
830 * The read stream will <b>not be owned</b> by
831 * the parser, it will still be managed (i.e. closed if
832 * end-of-stream is reacher, or parser close method called)
833 * if (and only if) {@link com.fasterxml.jackson.core.JsonParser.Feature#AUTO_CLOSE_SOURCE}
834 * is enabled.
Tatu Salorantaf15531c2011-12-22 23:00:40 -0800835 *
836 * @param r Reader to use for reading JSON content to parse
Tatu Saloranta68194922012-11-15 20:34:29 -0800837 *
838 * @since 2.1
Tatu Salorantaf15531c2011-12-22 23:00:40 -0800839 */
Tatu Saloranta32e4e912014-01-26 19:59:28 -0800840 public JsonParser createParser(Reader r) throws IOException, JsonParseException {
Tatu Salorantaf15531c2011-12-22 23:00:40 -0800841 // false -> we do NOT own Reader (did not create it)
842 IOContext ctxt = _createContext(r, false);
Tatu Saloranta896000f2014-04-19 12:53:40 -0700843 return _createParser(_decorate(r, ctxt), ctxt);
Tatu Salorantaf15531c2011-12-22 23:00:40 -0800844 }
845
846 /**
847 * Method for constructing parser for parsing
848 * the contents of given byte array.
Tatu Saloranta68194922012-11-15 20:34:29 -0800849 *
850 * @since 2.1
Tatu Salorantaf15531c2011-12-22 23:00:40 -0800851 */
Tatu Saloranta32e4e912014-01-26 19:59:28 -0800852 public JsonParser createParser(byte[] data) throws IOException, JsonParseException {
Tatu Salorantaf15531c2011-12-22 23:00:40 -0800853 IOContext ctxt = _createContext(data, true);
Tatu Salorantaf15531c2011-12-22 23:00:40 -0800854 if (_inputDecorator != null) {
855 InputStream in = _inputDecorator.decorate(ctxt, data, 0, data.length);
856 if (in != null) {
Tatu Salorantaeeb2fbd2012-05-28 22:00:08 -0700857 return _createParser(in, ctxt);
Tatu Salorantaf15531c2011-12-22 23:00:40 -0800858 }
859 }
Tatu Salorantaeeb2fbd2012-05-28 22:00:08 -0700860 return _createParser(data, 0, data.length, ctxt);
Tatu Salorantaf15531c2011-12-22 23:00:40 -0800861 }
862
863 /**
864 * Method for constructing parser for parsing
865 * the contents of given byte array.
866 *
867 * @param data Buffer that contains data to parse
868 * @param offset Offset of the first data byte within buffer
869 * @param len Length of contents to parse within buffer
Tatu Saloranta68194922012-11-15 20:34:29 -0800870 *
871 * @since 2.1
Tatu Salorantaf15531c2011-12-22 23:00:40 -0800872 */
Tatu Saloranta32e4e912014-01-26 19:59:28 -0800873 public JsonParser createParser(byte[] data, int offset, int len) throws IOException, JsonParseException {
Tatu Salorantaf15531c2011-12-22 23:00:40 -0800874 IOContext ctxt = _createContext(data, true);
875 // [JACKSON-512]: allow wrapping with InputDecorator
876 if (_inputDecorator != null) {
877 InputStream in = _inputDecorator.decorate(ctxt, data, offset, len);
878 if (in != null) {
Tatu Salorantaeeb2fbd2012-05-28 22:00:08 -0700879 return _createParser(in, ctxt);
Tatu Salorantaf15531c2011-12-22 23:00:40 -0800880 }
881 }
Tatu Saloranta68194922012-11-15 20:34:29 -0800882 return _createParser(data, offset, len, ctxt);
Tatu Salorantaf15531c2011-12-22 23:00:40 -0800883 }
884
885 /**
886 * Method for constructing parser for parsing
887 * contents of given String.
Tatu Saloranta68194922012-11-15 20:34:29 -0800888 *
889 * @since 2.1
Tatu Salorantaf15531c2011-12-22 23:00:40 -0800890 */
Tatu Saloranta32e4e912014-01-26 19:59:28 -0800891 public JsonParser createParser(String content) throws IOException, JsonParseException {
Tatu64aa9d22014-04-18 14:07:38 -0700892 final int strLen = content.length();
893 // Actually, let's use this for medium-sized content, up to 64kB chunk (32kb char)
Tatu Salorantad7cbb642016-05-13 13:23:04 -0700894 if ((_inputDecorator != null) || (strLen > 0x8000) || !canUseCharArrays()) {
Tatu64aa9d22014-04-18 14:07:38 -0700895 // easier to just wrap in a Reader than extend InputDecorator; or, if content
896 // is too long for us to copy it over
897 return createParser(new StringReader(content));
Tatu Salorantaf15531c2011-12-22 23:00:40 -0800898 }
Tatu64aa9d22014-04-18 14:07:38 -0700899 IOContext ctxt = _createContext(content, true);
Tatu Saloranta84dc1842014-04-18 21:07:57 -0700900 char[] buf = ctxt.allocTokenBuffer(strLen);
Tatu64aa9d22014-04-18 14:07:38 -0700901 content.getChars(0, strLen, buf, 0);
902 return _createParser(buf, 0, strLen, ctxt, true);
903 }
904
905 /**
906 * Method for constructing parser for parsing
907 * contents of given char array.
908 *
909 * @since 2.4
910 */
911 public JsonParser createParser(char[] content) throws IOException {
912 return createParser(content, 0, content.length);
913 }
914
915 /**
Tatu Saloranta896000f2014-04-19 12:53:40 -0700916 * Method for constructing parser for parsing contents of given char array.
Tatu64aa9d22014-04-18 14:07:38 -0700917 *
918 * @since 2.4
919 */
920 public JsonParser createParser(char[] content, int offset, int len) throws IOException {
921 if (_inputDecorator != null) { // easier to just wrap in a Reader than extend InputDecorator
922 return createParser(new CharArrayReader(content, offset, len));
923 }
Tatu Saloranta896000f2014-04-19 12:53:40 -0700924 return _createParser(content, offset, len, _createContext(content, true),
925 // important: buffer is NOT recyclable, as it's from caller
926 false);
Tatu Salorantaf15531c2011-12-22 23:00:40 -0800927 }
928
Tatu Salorantad7cbb642016-05-13 13:23:04 -0700929 /**
Tatu Saloranta81fb43c2017-05-17 18:25:34 -0700930 * Optional method for constructing parser for reading contents from specified {@link DataInput}
931 * instance.
932 *<p>
933 * If this factory does not support {@link DataInput} as source,
934 * will throw {@link UnsupportedOperationException}
935 *
Tatu Salorantad7cbb642016-05-13 13:23:04 -0700936 * @since 2.8
937 */
938 public JsonParser createParser(DataInput in) throws IOException {
939 IOContext ctxt = _createContext(in, false);
940 return _createParser(_decorate(in, ctxt), ctxt);
941 }
942
Tatu Salorantaf15531c2011-12-22 23:00:40 -0800943 /*
944 /**********************************************************
Tatu Saloranta81fb43c2017-05-17 18:25:34 -0700945 /* Parser factories, non-blocking (async) sources
946 /**********************************************************
947 */
948
949 /**
950 * Optional method for constructing parser for non-blocking parsing
951 * via {@link com.fasterxml.jackson.core.async.ByteArrayFeeder}
952 * interface (accessed using {@link JsonParser#getNonBlockingInputFeeder()}
953 * from constructed instance).
954 *<p>
955 * If this factory does not support non-blocking parsing (either at all,
956 * or from byte array),
957 * will throw {@link UnsupportedOperationException}
958 *
959 * @since 2.9
960 */
961 public JsonParser createNonBlockingByteArrayParser() throws IOException
962 {
963 // 17-May-2017, tatu: Need to take care not to accidentally create JSON parser
964 // for non-JSON input:
965 _requireJSONFactory("Non-blocking source not (yet?) support for this format (%s)");
966 IOContext ctxt = _createContext(null, false);
967 ByteQuadsCanonicalizer can = _byteSymbolCanonicalizer.makeChild(_factoryFeatures);
968 return new NonBlockingJsonParser(ctxt, _parserFeatures, can);
969 }
970
971 /*
972 /**********************************************************
Tatu Salorantad302ae02015-12-27 21:53:15 -0800973 /* Parser factories (old ones, pre-2.2)
Tatu Saloranta68194922012-11-15 20:34:29 -0800974 /**********************************************************
975 */
976
977 /**
978 * Method for constructing JSON parser instance to parse
Dmitry Spikhalskiy5590fcf2015-11-29 20:27:14 +0300979 * contents of specified file.
Dmitry Spikhalskiy5590fcf2015-11-29 20:27:14 +0300980 *<p>
981 * Encoding is auto-detected from contents according to JSON
982 * specification recommended mechanism. Json specification
983 * supports only UTF-8, UTF-16 and UTF-32 as valid encodings,
984 * so auto-detection implemented only for this charsets.
985 * For other charsets use {@link #createParser(java.io.Reader)}.
986 *
Tatu Saloranta68194922012-11-15 20:34:29 -0800987 *<p>
988 * Underlying input stream (needed for reading contents)
989 * will be <b>owned</b> (and managed, i.e. closed as need be) by
990 * the parser, since caller has no access to it.
Tatu Saloranta68194922012-11-15 20:34:29 -0800991 *
992 * @param f File that contains JSON content to parse
993 *
994 * @deprecated Since 2.2, use {@link #createParser(File)} instead.
995 */
996 @Deprecated
Tatu Salorantaefc23672013-12-30 19:09:39 -0800997 public JsonParser createJsonParser(File f) throws IOException, JsonParseException {
Tatu Saloranta68194922012-11-15 20:34:29 -0800998 return createParser(f);
999 }
1000
1001 /**
1002 * Method for constructing JSON parser instance to parse
1003 * contents of resource reference by given URL.
Dmitry Spikhalskiy5590fcf2015-11-29 20:27:14 +03001004 *
1005 *<p>
1006 * Encoding is auto-detected from contents according to JSON
1007 * specification recommended mechanism. Json specification
1008 * supports only UTF-8, UTF-16 and UTF-32 as valid encodings,
1009 * so auto-detection implemented only for this charsets.
1010 * For other charsets use {@link #createParser(java.io.Reader)}.
1011 *
Tatu Saloranta68194922012-11-15 20:34:29 -08001012 *<p>
1013 * Underlying input stream (needed for reading contents)
1014 * will be <b>owned</b> (and managed, i.e. closed as need be) by
1015 * the parser, since caller has no access to it.
Tatu Saloranta68194922012-11-15 20:34:29 -08001016 *
1017 * @param url URL pointing to resource that contains JSON content to parse
1018 *
1019 * @deprecated Since 2.2, use {@link #createParser(URL)} instead.
1020 */
1021 @Deprecated
Tatu Salorantaefc23672013-12-30 19:09:39 -08001022 public JsonParser createJsonParser(URL url) throws IOException, JsonParseException {
Tatu Saloranta68194922012-11-15 20:34:29 -08001023 return createParser(url);
1024 }
1025
1026 /**
1027 * Method for constructing JSON parser instance to parse
1028 * the contents accessed via specified input stream.
1029 *<p>
1030 * The input stream will <b>not be owned</b> by
1031 * the parser, it will still be managed (i.e. closed if
1032 * end-of-stream is reacher, or parser close method called)
1033 * if (and only if) {@link com.fasterxml.jackson.core.JsonParser.Feature#AUTO_CLOSE_SOURCE}
1034 * is enabled.
1035 *<p>
Dmitry Spikhalskiy5590fcf2015-11-29 20:27:14 +03001036 *
Tatu Saloranta68194922012-11-15 20:34:29 -08001037 * Note: no encoding argument is taken since it can always be
Dmitry Spikhalskiy5590fcf2015-11-29 20:27:14 +03001038 * auto-detected as suggested by JSON RFC. Json specification
1039 * supports only UTF-8, UTF-16 and UTF-32 as valid encodings,
1040 * so auto-detection implemented only for this charsets.
1041 * For other charsets use {@link #createParser(java.io.Reader)}.
Tatu Saloranta68194922012-11-15 20:34:29 -08001042 *
1043 * @param in InputStream to use for reading JSON content to parse
1044 *
1045 * @deprecated Since 2.2, use {@link #createParser(InputStream)} instead.
1046 */
1047 @Deprecated
Tatu Salorantaefc23672013-12-30 19:09:39 -08001048 public JsonParser createJsonParser(InputStream in) throws IOException, JsonParseException {
Tatu Saloranta68194922012-11-15 20:34:29 -08001049 return createParser(in);
1050 }
1051
1052 /**
1053 * Method for constructing parser for parsing
1054 * the contents accessed via specified Reader.
1055 <p>
1056 * The read stream will <b>not be owned</b> by
1057 * the parser, it will still be managed (i.e. closed if
1058 * end-of-stream is reacher, or parser close method called)
1059 * if (and only if) {@link com.fasterxml.jackson.core.JsonParser.Feature#AUTO_CLOSE_SOURCE}
1060 * is enabled.
Tatu Saloranta68194922012-11-15 20:34:29 -08001061 *
1062 * @param r Reader to use for reading JSON content to parse
1063 *
1064 * @deprecated Since 2.2, use {@link #createParser(Reader)} instead.
1065 */
1066 @Deprecated
Tatu Salorantaefc23672013-12-30 19:09:39 -08001067 public JsonParser createJsonParser(Reader r) throws IOException, JsonParseException {
Tatu Saloranta68194922012-11-15 20:34:29 -08001068 return createParser(r);
1069 }
1070
1071 /**
Tatu Salorantaefc23672013-12-30 19:09:39 -08001072 * Method for constructing parser for parsing the contents of given byte array.
Tatu Saloranta68194922012-11-15 20:34:29 -08001073 *
1074 * @deprecated Since 2.2, use {@link #createParser(byte[])} instead.
1075 */
1076 @Deprecated
Tatu Salorantaefc23672013-12-30 19:09:39 -08001077 public JsonParser createJsonParser(byte[] data) throws IOException, JsonParseException {
Tatu Saloranta68194922012-11-15 20:34:29 -08001078 return createParser(data);
1079 }
1080
1081 /**
1082 * Method for constructing parser for parsing
1083 * the contents of given byte array.
Tatu Saloranta68194922012-11-15 20:34:29 -08001084 *
1085 * @param data Buffer that contains data to parse
1086 * @param offset Offset of the first data byte within buffer
1087 * @param len Length of contents to parse within buffer
1088 *
1089 * @deprecated Since 2.2, use {@link #createParser(byte[],int,int)} instead.
1090 */
1091 @Deprecated
Tatu Salorantaefc23672013-12-30 19:09:39 -08001092 public JsonParser createJsonParser(byte[] data, int offset, int len) throws IOException, JsonParseException {
Tatu Saloranta68194922012-11-15 20:34:29 -08001093 return createParser(data, offset, len);
1094 }
1095
1096 /**
1097 * Method for constructing parser for parsing
1098 * contents of given String.
1099 *
1100 * @deprecated Since 2.2, use {@link #createParser(String)} instead.
1101 */
1102 @Deprecated
Tatu Salorantaefc23672013-12-30 19:09:39 -08001103 public JsonParser createJsonParser(String content) throws IOException, JsonParseException {
Tatu Saloranta68194922012-11-15 20:34:29 -08001104 return createParser(content);
1105 }
1106
1107 /*
1108 /**********************************************************
Tatu Salorantafeaabd12012-07-22 23:03:41 -07001109 /* Generator factories, new (as per [Issue-25]
Tatu Salorantaf15531c2011-12-22 23:00:40 -08001110 /**********************************************************
1111 */
1112
1113 /**
1114 * Method for constructing JSON generator for writing JSON content
1115 * using specified output stream.
1116 * Encoding to use must be specified, and needs to be one of available
1117 * types (as per JSON specification).
1118 *<p>
1119 * Underlying stream <b>is NOT owned</b> by the generator constructed,
1120 * so that generator will NOT close the output stream when
1121 * {@link JsonGenerator#close} is called (unless auto-closing
1122 * feature,
1123 * {@link com.fasterxml.jackson.core.JsonGenerator.Feature#AUTO_CLOSE_TARGET}
1124 * is enabled).
1125 * Using application needs to close it explicitly if this is the case.
1126 *<p>
1127 * Note: there are formats that use fixed encoding (like most binary data formats)
1128 * and that ignore passed in encoding.
Tatu Salorantafeaabd12012-07-22 23:03:41 -07001129 *
1130 * @param out OutputStream to use for writing JSON content
1131 * @param enc Character encoding to use
Tatu Saloranta4ab04ce2012-11-15 20:42:16 -08001132 *
1133 * @since 2.1
Tatu Salorantafeaabd12012-07-22 23:03:41 -07001134 */
1135 public JsonGenerator createGenerator(OutputStream out, JsonEncoding enc)
1136 throws IOException
1137 {
Tatu Saloranta4ab04ce2012-11-15 20:42:16 -08001138 // false -> we won't manage the stream unless explicitly directed to
1139 IOContext ctxt = _createContext(out, false);
1140 ctxt.setEncoding(enc);
1141 if (enc == JsonEncoding.UTF8) {
Tatu Saloranta896000f2014-04-19 12:53:40 -07001142 return _createUTF8Generator(_decorate(out, ctxt), ctxt);
Tatu Saloranta4ab04ce2012-11-15 20:42:16 -08001143 }
1144 Writer w = _createWriter(out, enc, ctxt);
Tatu Saloranta896000f2014-04-19 12:53:40 -07001145 return _createGenerator(_decorate(w, ctxt), ctxt);
Tatu Salorantafeaabd12012-07-22 23:03:41 -07001146 }
1147
1148 /**
Tatu Saloranta4ab04ce2012-11-15 20:42:16 -08001149 * Convenience method for constructing generator that uses default
1150 * encoding of the format (UTF-8 for JSON and most other data formats).
1151 *<p>
1152 * Note: there are formats that use fixed encoding (like most binary data formats).
1153 *
1154 * @since 2.1
1155 */
1156 public JsonGenerator createGenerator(OutputStream out) throws IOException {
1157 return createGenerator(out, JsonEncoding.UTF8);
1158 }
1159
1160 /**
Tatu Salorantafeaabd12012-07-22 23:03:41 -07001161 * Method for constructing JSON generator for writing JSON content
1162 * using specified Writer.
1163 *<p>
1164 * Underlying stream <b>is NOT owned</b> by the generator constructed,
1165 * so that generator will NOT close the Reader when
1166 * {@link JsonGenerator#close} is called (unless auto-closing
1167 * feature,
1168 * {@link com.fasterxml.jackson.core.JsonGenerator.Feature#AUTO_CLOSE_TARGET} is enabled).
1169 * Using application needs to close it explicitly.
Tatu Salorantafeaabd12012-07-22 23:03:41 -07001170 *
Tatu Saloranta4ab04ce2012-11-15 20:42:16 -08001171 * @since 2.1
Tatu Salorantafeaabd12012-07-22 23:03:41 -07001172 *
Tatu Saloranta896000f2014-04-19 12:53:40 -07001173 * @param w Writer to use for writing JSON content
Tatu Salorantafeaabd12012-07-22 23:03:41 -07001174 */
Tatu Saloranta896000f2014-04-19 12:53:40 -07001175 public JsonGenerator createGenerator(Writer w) throws IOException {
1176 IOContext ctxt = _createContext(w, false);
1177 return _createGenerator(_decorate(w, ctxt), ctxt);
Tatu Salorantafeaabd12012-07-22 23:03:41 -07001178 }
1179
1180 /**
1181 * Method for constructing JSON generator for writing JSON content
1182 * to specified file, overwriting contents it might have (or creating
1183 * it if such file does not yet exist).
1184 * Encoding to use must be specified, and needs to be one of available
1185 * types (as per JSON specification).
1186 *<p>
1187 * Underlying stream <b>is owned</b> by the generator constructed,
1188 * i.e. generator will handle closing of file when
1189 * {@link JsonGenerator#close} is called.
Tatu Salorantafeaabd12012-07-22 23:03:41 -07001190 *
1191 * @param f File to write contents to
1192 * @param enc Character encoding to use
Tatu Saloranta4ab04ce2012-11-15 20:42:16 -08001193 *
1194 * @since 2.1
Tatu Salorantafeaabd12012-07-22 23:03:41 -07001195 */
Tatu Salorantab0a2e192014-04-10 09:36:07 -07001196 public JsonGenerator createGenerator(File f, JsonEncoding enc) throws IOException
Tatu Salorantafeaabd12012-07-22 23:03:41 -07001197 {
Tatu Saloranta4ab04ce2012-11-15 20:42:16 -08001198 OutputStream out = new FileOutputStream(f);
1199 // true -> yes, we have to manage the stream since we created it
1200 IOContext ctxt = _createContext(out, true);
1201 ctxt.setEncoding(enc);
1202 if (enc == JsonEncoding.UTF8) {
Tatu Saloranta896000f2014-04-19 12:53:40 -07001203 return _createUTF8Generator(_decorate(out, ctxt), ctxt);
Tatu Saloranta4ab04ce2012-11-15 20:42:16 -08001204 }
1205 Writer w = _createWriter(out, enc, ctxt);
Tatu Saloranta896000f2014-04-19 12:53:40 -07001206 return _createGenerator(_decorate(w, ctxt), ctxt);
Tatu Salorantafeaabd12012-07-22 23:03:41 -07001207 }
1208
Tatu Saloranta38b3ef12016-05-03 18:08:31 -07001209 /**
1210 * Method for constructing generator for writing content using specified
1211 * {@link DataOutput} instance.
1212 *
1213 * @since 2.8
1214 */
1215 public JsonGenerator createGenerator(DataOutput out, JsonEncoding enc) throws IOException {
1216 return createGenerator(_createDataOutputWrapper(out), enc);
1217 }
1218
1219 /**
1220 * Convenience method for constructing generator that uses default
1221 * encoding of the format (UTF-8 for JSON and most other data formats).
1222 *<p>
1223 * Note: there are formats that use fixed encoding (like most binary data formats).
1224 *
1225 * @since 2.8
1226 */
1227 public JsonGenerator createGenerator(DataOutput out) throws IOException {
1228 return createGenerator(_createDataOutputWrapper(out), JsonEncoding.UTF8);
1229 }
1230
Tatu Salorantafeaabd12012-07-22 23:03:41 -07001231 /*
1232 /**********************************************************
Tatu Salorantad302ae02015-12-27 21:53:15 -08001233 /* Generator factories, old (pre-2.2)
Tatu Salorantafeaabd12012-07-22 23:03:41 -07001234 /**********************************************************
1235 */
1236
1237 /**
1238 * Method for constructing JSON generator for writing JSON content
1239 * using specified output stream.
1240 * Encoding to use must be specified, and needs to be one of available
1241 * types (as per JSON specification).
1242 *<p>
1243 * Underlying stream <b>is NOT owned</b> by the generator constructed,
1244 * so that generator will NOT close the output stream when
1245 * {@link JsonGenerator#close} is called (unless auto-closing
1246 * feature,
1247 * {@link com.fasterxml.jackson.core.JsonGenerator.Feature#AUTO_CLOSE_TARGET}
1248 * is enabled).
1249 * Using application needs to close it explicitly if this is the case.
1250 *<p>
1251 * Note: there are formats that use fixed encoding (like most binary data formats)
1252 * and that ignore passed in encoding.
Tatu Salorantaf15531c2011-12-22 23:00:40 -08001253 *
1254 * @param out OutputStream to use for writing JSON content
1255 * @param enc Character encoding to use
Tatu Saloranta4ab04ce2012-11-15 20:42:16 -08001256 *
1257 * @deprecated Since 2.2, use {@link #createGenerator(OutputStream, JsonEncoding)} instead.
Tatu Salorantaf15531c2011-12-22 23:00:40 -08001258 */
Tatu Saloranta4ab04ce2012-11-15 20:42:16 -08001259 @Deprecated
Tatu Salorantab0a2e192014-04-10 09:36:07 -07001260 public JsonGenerator createJsonGenerator(OutputStream out, JsonEncoding enc) throws IOException {
Tatu Saloranta4ab04ce2012-11-15 20:42:16 -08001261 return createGenerator(out, enc);
Tatu Salorantaf15531c2011-12-22 23:00:40 -08001262 }
1263
1264 /**
1265 * Method for constructing JSON generator for writing JSON content
1266 * using specified Writer.
1267 *<p>
1268 * Underlying stream <b>is NOT owned</b> by the generator constructed,
1269 * so that generator will NOT close the Reader when
1270 * {@link JsonGenerator#close} is called (unless auto-closing
1271 * feature,
1272 * {@link com.fasterxml.jackson.core.JsonGenerator.Feature#AUTO_CLOSE_TARGET} is enabled).
1273 * Using application needs to close it explicitly.
1274 *
1275 * @param out Writer to use for writing JSON content
Tatu Saloranta4ab04ce2012-11-15 20:42:16 -08001276 *
1277 * @deprecated Since 2.2, use {@link #createGenerator(Writer)} instead.
Tatu Salorantaf15531c2011-12-22 23:00:40 -08001278 */
Tatu Saloranta4ab04ce2012-11-15 20:42:16 -08001279 @Deprecated
Tatu Salorantab0a2e192014-04-10 09:36:07 -07001280 public JsonGenerator createJsonGenerator(Writer out) throws IOException {
Tatu Saloranta4ab04ce2012-11-15 20:42:16 -08001281 return createGenerator(out);
Tatu Salorantaf15531c2011-12-22 23:00:40 -08001282 }
1283
1284 /**
1285 * Convenience method for constructing generator that uses default
1286 * encoding of the format (UTF-8 for JSON and most other data formats).
1287 *<p>
1288 * Note: there are formats that use fixed encoding (like most binary data formats).
Tatu Saloranta4ab04ce2012-11-15 20:42:16 -08001289 *
1290 * @deprecated Since 2.2, use {@link #createGenerator(OutputStream)} instead.
Tatu Salorantaf15531c2011-12-22 23:00:40 -08001291 */
Tatu Saloranta4ab04ce2012-11-15 20:42:16 -08001292 @Deprecated
Tatu Salorantaf15531c2011-12-22 23:00:40 -08001293 public JsonGenerator createJsonGenerator(OutputStream out) throws IOException {
Tatu Saloranta4ab04ce2012-11-15 20:42:16 -08001294 return createGenerator(out, JsonEncoding.UTF8);
Tatu Salorantaf15531c2011-12-22 23:00:40 -08001295 }
Tatu Salorantaf15531c2011-12-22 23:00:40 -08001296
1297 /*
1298 /**********************************************************
1299 /* Factory methods used by factory for creating parser instances,
1300 /* overridable by sub-classes
1301 /**********************************************************
1302 */
1303
1304 /**
1305 * Overridable factory method that actually instantiates desired parser
1306 * given {@link InputStream} and context object.
1307 *<p>
1308 * This method is specifically designed to remain
1309 * compatible between minor versions so that sub-classes can count
1310 * on it being called as expected. That is, it is part of official
1311 * interface from sub-class perspective, although not a public
1312 * method available to users of factory implementations.
Tatu Salorantaeeb2fbd2012-05-28 22:00:08 -07001313 *
1314 * @since 2.1
Tatu Salorantaf15531c2011-12-22 23:00:40 -08001315 */
Tatu Salorantab0a2e192014-04-10 09:36:07 -07001316 protected JsonParser _createParser(InputStream in, IOContext ctxt) throws IOException {
Tatu Saloranta68194922012-11-15 20:34:29 -08001317 // As per [JACKSON-259], may want to fully disable canonicalization:
1318 return new ByteSourceJsonBootstrapper(ctxt, in).constructParser(_parserFeatures,
Tatu Salorantadccffbe2015-02-05 21:17:57 -08001319 _objectCodec, _byteSymbolCanonicalizer, _rootCharSymbols, _factoryFeatures);
Tatu Salorantaeeb2fbd2012-05-28 22:00:08 -07001320 }
1321
1322 /**
Tatu Salorantaf15531c2011-12-22 23:00:40 -08001323 * Overridable factory method that actually instantiates parser
1324 * using given {@link Reader} object for reading content.
1325 *<p>
1326 * This method is specifically designed to remain
1327 * compatible between minor versions so that sub-classes can count
1328 * on it being called as expected. That is, it is part of official
1329 * interface from sub-class perspective, although not a public
1330 * method available to users of factory implementations.
Tatu Salorantaeeb2fbd2012-05-28 22:00:08 -07001331 *
1332 * @since 2.1
Tatu Salorantaf15531c2011-12-22 23:00:40 -08001333 */
Tatu Salorantab0a2e192014-04-10 09:36:07 -07001334 protected JsonParser _createParser(Reader r, IOContext ctxt) throws IOException {
Tatu Saloranta68194922012-11-15 20:34:29 -08001335 return new ReaderBasedJsonParser(ctxt, _parserFeatures, r, _objectCodec,
Tatu Saloranta0541b3b2014-05-23 20:20:46 -07001336 _rootCharSymbols.makeChild(_factoryFeatures));
Tatu Salorantaeeb2fbd2012-05-28 22:00:08 -07001337 }
1338
1339 /**
Tatu Salorantaf15531c2011-12-22 23:00:40 -08001340 * Overridable factory method that actually instantiates parser
Tatu64aa9d22014-04-18 14:07:38 -07001341 * using given <code>char[]</code> object for accessing content.
1342 *
1343 * @since 2.4
1344 */
1345 protected JsonParser _createParser(char[] data, int offset, int len, IOContext ctxt,
1346 boolean recyclable) throws IOException {
1347 return new ReaderBasedJsonParser(ctxt, _parserFeatures, null, _objectCodec,
Tatu Saloranta0541b3b2014-05-23 20:20:46 -07001348 _rootCharSymbols.makeChild(_factoryFeatures),
1349 data, offset, offset+len, recyclable);
Tatu64aa9d22014-04-18 14:07:38 -07001350 }
1351
1352 /**
1353 * Overridable factory method that actually instantiates parser
Tatu Salorantaf15531c2011-12-22 23:00:40 -08001354 * using given {@link Reader} object for reading content
1355 * passed as raw byte array.
1356 *<p>
1357 * This method is specifically designed to remain
1358 * compatible between minor versions so that sub-classes can count
1359 * on it being called as expected. That is, it is part of official
1360 * interface from sub-class perspective, although not a public
1361 * method available to users of factory implementations.
1362 */
Tatu64aa9d22014-04-18 14:07:38 -07001363 protected JsonParser _createParser(byte[] data, int offset, int len, IOContext ctxt) throws IOException
Tatu Salorantaf15531c2011-12-22 23:00:40 -08001364 {
Tatu Saloranta68194922012-11-15 20:34:29 -08001365 return new ByteSourceJsonBootstrapper(ctxt, data, offset, len).constructParser(_parserFeatures,
Tatu Salorantadccffbe2015-02-05 21:17:57 -08001366 _objectCodec, _byteSymbolCanonicalizer, _rootCharSymbols, _factoryFeatures);
Tatu Salorantaeeb2fbd2012-05-28 22:00:08 -07001367 }
1368
Tatu Salorantad7cbb642016-05-13 13:23:04 -07001369 /**
Tatu Saloranta81fb43c2017-05-17 18:25:34 -07001370 * Optional factory method, expected to be overridden
1371 *
Tatu Salorantad7cbb642016-05-13 13:23:04 -07001372 * @since 2.8
1373 */
1374 protected JsonParser _createParser(DataInput input, IOContext ctxt) throws IOException
1375 {
1376 // 13-May-2016, tatu: Need to take care not to accidentally create JSON parser for
Tatu Saloranta81fb43c2017-05-17 18:25:34 -07001377 // non-JSON input.
1378 _requireJSONFactory("InputData source not (yet?) support for this format (%s)");
Tatu Saloranta155babc2016-05-17 16:13:19 -07001379 // Also: while we can't do full bootstrapping (due to read-ahead limitations), should
1380 // at least handle possible UTF-8 BOM
1381 int firstByte = ByteSourceJsonBootstrapper.skipUTF8BOM(input);
Tatu Salorantad7cbb642016-05-13 13:23:04 -07001382 ByteQuadsCanonicalizer can = _byteSymbolCanonicalizer.makeChild(_factoryFeatures);
1383 return new UTF8DataInputJsonParser(ctxt, _parserFeatures, input,
Tatu Saloranta155babc2016-05-17 16:13:19 -07001384 _objectCodec, can, firstByte);
Tatu Salorantad7cbb642016-05-13 13:23:04 -07001385 }
1386
Tatu Salorantaf15531c2011-12-22 23:00:40 -08001387 /*
1388 /**********************************************************
1389 /* Factory methods used by factory for creating generator instances,
1390 /* overridable by sub-classes
1391 /**********************************************************
1392 */
1393
1394 /**
1395 * Overridable factory method that actually instantiates generator for
1396 * given {@link Writer} and context object.
1397 *<p>
1398 * This method is specifically designed to remain
1399 * compatible between minor versions so that sub-classes can count
1400 * on it being called as expected. That is, it is part of official
1401 * interface from sub-class perspective, although not a public
1402 * method available to users of factory implementations.
1403 */
Tatu Salorantaefc23672013-12-30 19:09:39 -08001404 protected JsonGenerator _createGenerator(Writer out, IOContext ctxt) throws IOException
Tatu Salorantaeeb2fbd2012-05-28 22:00:08 -07001405 {
Tatu Salorantae6dfc692012-09-28 15:34:05 -07001406 WriterBasedJsonGenerator gen = new WriterBasedJsonGenerator(ctxt,
1407 _generatorFeatures, _objectCodec, out);
Tatu Salorantaf15531c2011-12-22 23:00:40 -08001408 if (_characterEscapes != null) {
1409 gen.setCharacterEscapes(_characterEscapes);
1410 }
Tatu Salorantae6dfc692012-09-28 15:34:05 -07001411 SerializableString rootSep = _rootValueSeparator;
1412 if (rootSep != DEFAULT_ROOT_VALUE_SEPARATOR) {
1413 gen.setRootValueSeparator(rootSep);
1414 }
Tatu Salorantaf15531c2011-12-22 23:00:40 -08001415 return gen;
1416 }
1417
1418 /**
1419 * Overridable factory method that actually instantiates generator for
1420 * given {@link OutputStream} and context object, using UTF-8 encoding.
1421 *<p>
1422 * This method is specifically designed to remain
1423 * compatible between minor versions so that sub-classes can count
1424 * on it being called as expected. That is, it is part of official
1425 * interface from sub-class perspective, although not a public
1426 * method available to users of factory implementations.
1427 */
Tatu Salorantaeeb2fbd2012-05-28 22:00:08 -07001428 protected JsonGenerator _createUTF8Generator(OutputStream out, IOContext ctxt) throws IOException {
Tatu Salorantae6dfc692012-09-28 15:34:05 -07001429 UTF8JsonGenerator gen = new UTF8JsonGenerator(ctxt,
1430 _generatorFeatures, _objectCodec, out);
Tatu Salorantaf15531c2011-12-22 23:00:40 -08001431 if (_characterEscapes != null) {
1432 gen.setCharacterEscapes(_characterEscapes);
1433 }
Tatu Salorantae6dfc692012-09-28 15:34:05 -07001434 SerializableString rootSep = _rootValueSeparator;
1435 if (rootSep != DEFAULT_ROOT_VALUE_SEPARATOR) {
1436 gen.setRootValueSeparator(rootSep);
1437 }
Tatu Salorantaf15531c2011-12-22 23:00:40 -08001438 return gen;
1439 }
1440
Tatu Salorantaf15531c2011-12-22 23:00:40 -08001441 protected Writer _createWriter(OutputStream out, JsonEncoding enc, IOContext ctxt) throws IOException
1442 {
1443 // note: this should not get called any more (caller checks, dispatches)
1444 if (enc == JsonEncoding.UTF8) { // We have optimized writer for UTF-8
1445 return new UTF8Writer(ctxt, out);
1446 }
1447 // not optimal, but should do unless we really care about UTF-16/32 encoding speed
1448 return new OutputStreamWriter(out, enc.getJavaName());
1449 }
Tatu Saloranta896000f2014-04-19 12:53:40 -07001450
1451 /*
1452 /**********************************************************
1453 /* Internal factory methods, decorator handling
1454 /**********************************************************
1455 */
1456
1457 /**
1458 * @since 2.4
1459 */
1460 protected final InputStream _decorate(InputStream in, IOContext ctxt) throws IOException {
1461 if (_inputDecorator != null) {
1462 InputStream in2 = _inputDecorator.decorate(ctxt, in);
1463 if (in2 != null) {
1464 return in2;
1465 }
1466 }
1467 return in;
1468 }
Tatu Salorantad7cbb642016-05-13 13:23:04 -07001469
Tatu Saloranta896000f2014-04-19 12:53:40 -07001470 /**
1471 * @since 2.4
1472 */
1473 protected final Reader _decorate(Reader in, IOContext ctxt) throws IOException {
1474 if (_inputDecorator != null) {
1475 Reader in2 = _inputDecorator.decorate(ctxt, in);
1476 if (in2 != null) {
1477 return in2;
1478 }
1479 }
1480 return in;
1481 }
1482
1483 /**
Tatu Salorantad7cbb642016-05-13 13:23:04 -07001484 * @since 2.8
1485 */
1486 protected final DataInput _decorate(DataInput in, IOContext ctxt) throws IOException {
1487 if (_inputDecorator != null) {
1488 DataInput in2 = _inputDecorator.decorate(ctxt, in);
1489 if (in2 != null) {
1490 return in2;
1491 }
1492 }
1493 return in;
1494 }
1495
1496 /**
Tatu Saloranta896000f2014-04-19 12:53:40 -07001497 * @since 2.4
1498 */
1499 protected final OutputStream _decorate(OutputStream out, IOContext ctxt) throws IOException {
1500 if (_outputDecorator != null) {
1501 OutputStream out2 = _outputDecorator.decorate(ctxt, out);
1502 if (out2 != null) {
1503 return out2;
1504 }
1505 }
1506 return out;
1507 }
1508
1509 /**
1510 * @since 2.4
1511 */
1512 protected final Writer _decorate(Writer out, IOContext ctxt) throws IOException {
1513 if (_outputDecorator != null) {
1514 Writer out2 = _outputDecorator.decorate(ctxt, out);
1515 if (out2 != null) {
1516 return out2;
1517 }
1518 }
1519 return out;
1520 }
Tatu Salorantaf15531c2011-12-22 23:00:40 -08001521
1522 /*
1523 /**********************************************************
1524 /* Internal factory methods, other
1525 /**********************************************************
1526 */
1527
1528 /**
Tatu Salorantaf15531c2011-12-22 23:00:40 -08001529 * Method used by factory to create buffer recycler instances
1530 * for parsers and generators.
1531 *<p>
1532 * Note: only public to give access for <code>ObjectMapper</code>
1533 */
1534 public BufferRecycler _getBufferRecycler()
1535 {
Tatu Saloranta8891c0c2015-04-23 22:47:05 -07001536 /* 23-Apr-2015, tatu: Let's allow disabling of buffer recycling
1537 * scheme, for cases where it is considered harmful (possibly
1538 * on Android, for example)
1539 */
Tatu Salorantaddec51c2017-02-28 16:07:04 -08001540 if (Feature.USE_THREAD_LOCAL_FOR_BUFFER_RECYCLING.enabledIn(_factoryFeatures)) {
Tatu Saloranta8891c0c2015-04-23 22:47:05 -07001541 SoftReference<BufferRecycler> ref = _recyclerRef.get();
happyelf833de412016-07-23 11:10:21 +08001542 BufferRecycler br = (ref == null) ? null : ref.get();
Tatu Saloranta8891c0c2015-04-23 22:47:05 -07001543
1544 if (br == null) {
1545 br = new BufferRecycler();
1546 _recyclerRef.set(new SoftReference<BufferRecycler>(br));
1547 }
happyelf833de412016-07-23 11:10:21 +08001548 return br;
Tatu Salorantaf15531c2011-12-22 23:00:40 -08001549 }
happyelf833de412016-07-23 11:10:21 +08001550 return new BufferRecycler();
Tatu Salorantaf15531c2011-12-22 23:00:40 -08001551 }
Tatu Salorantad302ae02015-12-27 21:53:15 -08001552
Tatu Salorantaf15531c2011-12-22 23:00:40 -08001553 /**
Tatu Saloranta896000f2014-04-19 12:53:40 -07001554 * Overridable factory method that actually instantiates desired
1555 * context object.
1556 */
1557 protected IOContext _createContext(Object srcRef, boolean resourceManaged) {
1558 return new IOContext(_getBufferRecycler(), srcRef, resourceManaged);
1559 }
Tatu Salorantad302ae02015-12-27 21:53:15 -08001560
Tatu Saloranta896000f2014-04-19 12:53:40 -07001561 /**
Tatu Saloranta38b3ef12016-05-03 18:08:31 -07001562 * @since 2.8
1563 */
1564 protected OutputStream _createDataOutputWrapper(DataOutput out) {
1565 return new DataOutputAsStream(out);
1566 }
1567
1568 /**
Tatu Salorantaf15531c2011-12-22 23:00:40 -08001569 * Helper methods used for constructing an optimal stream for
1570 * parsers to use, when input is to be read from an URL.
1571 * This helps when reading file content via URL.
1572 */
Tatu Salorantaefc23672013-12-30 19:09:39 -08001573 protected InputStream _optimizedStreamFromURL(URL url) throws IOException {
Tatu Salorantaf15531c2011-12-22 23:00:40 -08001574 if ("file".equals(url.getProtocol())) {
1575 /* Can not do this if the path refers
1576 * to a network drive on windows. This fixes the problem;
1577 * might not be needed on all platforms (NFS?), but should not
1578 * matter a lot: performance penalty of extra wrapping is more
1579 * relevant when accessing local file system.
1580 */
1581 String host = url.getHost();
1582 if (host == null || host.length() == 0) {
Tatu Saloranta38b3ef12016-05-03 18:08:31 -07001583 // [core#48]: Let's try to avoid probs with URL encoded stuff
Tatu Saloranta61d5bdd2013-01-11 19:02:01 -08001584 String path = url.getPath();
1585 if (path.indexOf('%') < 0) {
1586 return new FileInputStream(url.getPath());
1587
1588 }
1589 // otherwise, let's fall through and let URL decoder do its magic
Tatu Salorantaf15531c2011-12-22 23:00:40 -08001590 }
1591 }
1592 return url.openStream();
1593 }
Tatu Saloranta81fb43c2017-05-17 18:25:34 -07001594
1595 /*
1596 /**********************************************************
1597 /* Internal helper methods
1598 /**********************************************************
1599 */
1600
1601 /**
1602 * Helper method called to work around the problem of this class both defining
1603 * general API for constructing parsers+generators AND implementing the API
1604 * for JSON handling. Problem here is that when adding new functionality
1605 * via factory methods, it is not possible to leave these methods abstract
1606 * (because we are implementing them for JSON); but there is risk that
1607 * sub-classes do not override them all (plus older version can not implement).
1608 * So a work-around is to add a check to ensure that factory is still one
1609 * used for JSON; and if not, make base implementation of a factory method fail.
1610 *
1611 * @since 2.9
1612 */
1613 private final void _requireJSONFactory(String msg) {
1614 // NOTE: since we only really care about whether this is standard JSON-backed factory,
1615 // or its sub-class / delegated to one, no need to check for equality, identity is enough
1616 String format = getFormatName();
1617 if (format != FORMAT_NAME_JSON) {
1618 throw new UnsupportedOperationException(String.format(msg, format));
1619 }
1620 }
Tatu Salorantaf15531c2011-12-22 23:00:40 -08001621}