blob: fea6fe683418a009a0dcf755d311892ddf50275c [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 */
Tatu Saloranta89986a82017-06-01 00:01:38 -0700418 public boolean canParseAsync() {
419 // 31-May-2017, tatu: Jackson 2.9 does support async parsing for JSON,
420 // but not all other formats, so need to do this:
421 return _isJSONFactory();
422 }
Tatu Saloranta78b01182017-05-10 21:02:18 -0700423
424 /**
Cowtowncoder2e262b92015-05-27 17:32:17 -0700425 * Method for accessing kind of {@link FormatFeature} that a parser
426 * {@link JsonParser} produced by this factory would accept, if any;
427 * <code>null</code> returned if none.
428 *
429 * @since 2.6
430 */
431 public Class<? extends FormatFeature> getFormatReadFeatureType() {
432 return null;
433 }
434
435 /**
436 * Method for accessing kind of {@link FormatFeature} that a parser
437 * {@link JsonGenerator} produced by this factory would accept, if any;
438 * <code>null</code> returned if none.
439 *
440 * @since 2.6
441 */
442 public Class<? extends FormatFeature> getFormatWriteFeatureType() {
443 return null;
444 }
Tatu Salorantaf15531c2011-12-22 23:00:40 -0800445 /*
446 /**********************************************************
Cowtowncoder2e262b92015-05-27 17:32:17 -0700447 /* Format detection functionality
Tatu Salorantaf15531c2011-12-22 23:00:40 -0800448 /**********************************************************
449 */
450
451 /**
Tatu Saloranta1bdf0262012-08-24 14:43:17 -0700452 * Method that can be used to quickly check whether given schema
453 * is something that parsers and/or generators constructed by this
454 * factory could use. Note that this means possible use, at the level
455 * of data format (i.e. schema is for same data format as parsers and
456 * generators this factory constructs); individual schema instances
457 * may have further usage restrictions.
458 *
459 * @since 2.1
460 */
461 public boolean canUseSchema(FormatSchema schema) {
Tatu Saloranta244ddd12016-05-14 15:11:04 -0700462 if (schema == null){
463 return false;
464 }
Tatu Saloranta1bdf0262012-08-24 14:43:17 -0700465 String ourFormat = getFormatName();
466 return (ourFormat != null) && ourFormat.equals(schema.getSchemaType());
467 }
468
469 /**
Tatu Salorantaf15531c2011-12-22 23:00:40 -0800470 * Method that returns short textual id identifying format
471 * this factory supports.
472 *<p>
473 * Note: sub-classes should override this method; default
474 * implementation will return null for all sub-classes
475 */
476 public String getFormatName()
477 {
478 /* Somewhat nasty check: since we can't make this abstract
479 * (due to backwards compatibility concerns), need to prevent
480 * format name "leakage"
481 */
482 if (getClass() == JsonFactory.class) {
483 return FORMAT_NAME_JSON;
484 }
485 return null;
486 }
487
Cowtowncoder2e262b92015-05-27 17:32:17 -0700488 /**
489 * Convenience method for trying to determine whether input via given accessor
490 * is of format type supported by this factory.
491 */
Tatu Salorantaf15531c2011-12-22 23:00:40 -0800492 public MatchStrength hasFormat(InputAccessor acc) throws IOException
493 {
494 // since we can't keep this abstract, only implement for "vanilla" instance
495 if (getClass() == JsonFactory.class) {
496 return hasJSONFormat(acc);
497 }
498 return null;
499 }
500
Tatu Salorantaad2df5f2012-08-22 20:55:49 -0700501 /**
502 * Method that can be called to determine if a custom
503 * {@link ObjectCodec} is needed for binding data parsed
504 * using {@link JsonParser} constructed by this factory
505 * (which typically also implies the same for serialization
506 * with {@link JsonGenerator}).
507 *
508 * @return True if custom codec is needed with parsers and
509 * generators created by this factory; false if a general
510 * {@link ObjectCodec} is enough
511 *
512 * @since 2.1
513 */
514 public boolean requiresCustomCodec() {
515 return false;
516 }
517
518 /**
519 * Helper method that can be called to determine if content accessed
520 * using given accessor seems to be JSON content.
521 */
Tatu Salorantaf15531c2011-12-22 23:00:40 -0800522 protected MatchStrength hasJSONFormat(InputAccessor acc) throws IOException
523 {
524 return ByteSourceJsonBootstrapper.hasJSONFormat(acc);
Tatu Salorantaad2df5f2012-08-22 20:55:49 -0700525 }
526
Tatu Salorantaf15531c2011-12-22 23:00:40 -0800527 /*
528 /**********************************************************
529 /* Versioned
530 /**********************************************************
531 */
532
Tatu Saloranta68d79dd2013-01-10 21:13:46 -0800533 @Override
Tatu Salorantaf15531c2011-12-22 23:00:40 -0800534 public Version version() {
Tatu Saloranta68d79dd2013-01-10 21:13:46 -0800535 return PackageVersion.VERSION;
Tatu Salorantaf15531c2011-12-22 23:00:40 -0800536 }
537
538 /*
539 /**********************************************************
Tatu07351902012-01-19 13:12:13 -0800540 /* Configuration, factory features
Tatu Salorantaf15531c2011-12-22 23:00:40 -0800541 /**********************************************************
542 */
543
544 /**
545 * Method for enabling or disabling specified parser feature
546 * (check {@link JsonParser.Feature} for list of features)
547 */
Tatu07351902012-01-19 13:12:13 -0800548 public final JsonFactory configure(JsonFactory.Feature f, boolean state) {
549 return state ? enable(f) : disable(f);
550 }
551
552 /**
553 * Method for enabling specified parser feature
554 * (check {@link JsonFactory.Feature} for list of features)
555 */
556 public JsonFactory enable(JsonFactory.Feature f) {
557 _factoryFeatures |= f.getMask();
Tatu Salorantaf15531c2011-12-22 23:00:40 -0800558 return this;
559 }
560
561 /**
Tatu07351902012-01-19 13:12:13 -0800562 * Method for disabling specified parser features
563 * (check {@link JsonFactory.Feature} for list of features)
564 */
565 public JsonFactory disable(JsonFactory.Feature f) {
566 _factoryFeatures &= ~f.getMask();
567 return this;
568 }
569
570 /**
571 * Checked whether specified parser feature is enabled.
572 */
573 public final boolean isEnabled(JsonFactory.Feature f) {
574 return (_factoryFeatures & f.getMask()) != 0;
575 }
576
577 /*
578 /**********************************************************
579 /* Configuration, parser configuration
580 /**********************************************************
581 */
582
583 /**
584 * Method for enabling or disabling specified parser feature
585 * (check {@link JsonParser.Feature} for list of features)
586 */
587 public final JsonFactory configure(JsonParser.Feature f, boolean state) {
588 return state ? enable(f) : disable(f);
589 }
590
591 /**
Tatu Salorantaf15531c2011-12-22 23:00:40 -0800592 * Method for enabling specified parser feature
593 * (check {@link JsonParser.Feature} for list of features)
594 */
595 public JsonFactory enable(JsonParser.Feature f) {
596 _parserFeatures |= f.getMask();
597 return this;
598 }
599
600 /**
601 * Method for disabling specified parser features
602 * (check {@link JsonParser.Feature} for list of features)
603 */
604 public JsonFactory disable(JsonParser.Feature f) {
605 _parserFeatures &= ~f.getMask();
606 return this;
607 }
608
609 /**
610 * Checked whether specified parser feature is enabled.
611 */
612 public final boolean isEnabled(JsonParser.Feature f) {
613 return (_parserFeatures & f.getMask()) != 0;
614 }
615
616 /**
617 * Method for getting currently configured input decorator (if any;
618 * there is no default decorator).
619 */
620 public InputDecorator getInputDecorator() {
621 return _inputDecorator;
622 }
623
624 /**
625 * Method for overriding currently configured input decorator
626 */
627 public JsonFactory setInputDecorator(InputDecorator d) {
628 _inputDecorator = d;
629 return this;
630 }
631
632 /*
633 /**********************************************************
634 /* Configuration, generator settings
635 /**********************************************************
636 */
637
638 /**
639 * Method for enabling or disabling specified generator feature
640 * (check {@link JsonGenerator.Feature} for list of features)
641 */
642 public final JsonFactory configure(JsonGenerator.Feature f, boolean state) {
Tatu07351902012-01-19 13:12:13 -0800643 return state ? enable(f) : disable(f);
Tatu Salorantaf15531c2011-12-22 23:00:40 -0800644 }
645
646
647 /**
648 * Method for enabling specified generator features
649 * (check {@link JsonGenerator.Feature} for list of features)
650 */
651 public JsonFactory enable(JsonGenerator.Feature f) {
652 _generatorFeatures |= f.getMask();
653 return this;
654 }
655
656 /**
657 * Method for disabling specified generator feature
658 * (check {@link JsonGenerator.Feature} for list of features)
659 */
660 public JsonFactory disable(JsonGenerator.Feature f) {
661 _generatorFeatures &= ~f.getMask();
662 return this;
663 }
664
665 /**
666 * Check whether specified generator feature is enabled.
667 */
668 public final boolean isEnabled(JsonGenerator.Feature f) {
669 return (_generatorFeatures & f.getMask()) != 0;
670 }
671
672 /**
673 * Method for accessing custom escapes factory uses for {@link JsonGenerator}s
674 * it creates.
675 */
Tatu Saloranta32e4e912014-01-26 19:59:28 -0800676 public CharacterEscapes getCharacterEscapes() { return _characterEscapes; }
Tatu Salorantaf15531c2011-12-22 23:00:40 -0800677
678 /**
679 * Method for defining custom escapes factory uses for {@link JsonGenerator}s
680 * it creates.
681 */
682 public JsonFactory setCharacterEscapes(CharacterEscapes esc) {
683 _characterEscapes = esc;
684 return this;
685 }
686
687 /**
688 * Method for getting currently configured output decorator (if any;
689 * there is no default decorator).
690 */
691 public OutputDecorator getOutputDecorator() {
692 return _outputDecorator;
693 }
694
695 /**
696 * Method for overriding currently configured output decorator
697 */
698 public JsonFactory setOutputDecorator(OutputDecorator d) {
699 _outputDecorator = d;
700 return this;
701 }
Tatu Salorantae6dfc692012-09-28 15:34:05 -0700702
703 /**
704 * Method that allows overriding String used for separating root-level
705 * JSON values (default is single space character)
706 *
707 * @param sep Separator to use, if any; null means that no separator is
708 * automatically added
709 *
710 * @since 2.1
711 */
712 public JsonFactory setRootValueSeparator(String sep) {
713 _rootValueSeparator = (sep == null) ? null : new SerializedString(sep);
714 return this;
715 }
716
717 /**
718 * @since 2.1
719 */
720 public String getRootValueSeparator() {
721 return (_rootValueSeparator == null) ? null : _rootValueSeparator.getValue();
722 }
Tatu Salorantaf15531c2011-12-22 23:00:40 -0800723
724 /*
725 /**********************************************************
726 /* Configuration, other
727 /**********************************************************
728 */
729
730 /**
731 * Method for associating a {@link ObjectCodec} (typically
Tatu Salorantad77350e2011-12-22 23:13:13 -0800732 * a <code>com.fasterxml.jackson.databind.ObjectMapper</code>)
733 * with this factory (and more importantly, parsers and generators
Tatu Salorantaf15531c2011-12-22 23:00:40 -0800734 * it constructs). This is needed to use data-binding methods
735 * of {@link JsonParser} and {@link JsonGenerator} instances.
736 */
737 public JsonFactory setCodec(ObjectCodec oc) {
738 _objectCodec = oc;
739 return this;
740 }
741
742 public ObjectCodec getCodec() { return _objectCodec; }
743
744 /*
745 /**********************************************************
Tatu Saloranta81fb43c2017-05-17 18:25:34 -0700746 /* Parser factories, traditional (blocking) I/O sources
Tatu Salorantaf15531c2011-12-22 23:00:40 -0800747 /**********************************************************
748 */
749
750 /**
751 * Method for constructing JSON parser instance to parse
Dmitry Spikhalskiy5590fcf2015-11-29 20:27:14 +0300752 * contents of specified file.
753 *
754 *<p>
755 * Encoding is auto-detected from contents according to JSON
756 * specification recommended mechanism. Json specification
757 * supports only UTF-8, UTF-16 and UTF-32 as valid encodings,
758 * so auto-detection implemented only for this charsets.
759 * For other charsets use {@link #createParser(java.io.Reader)}.
760 *
Tatu Salorantaf15531c2011-12-22 23:00:40 -0800761 *<p>
762 * Underlying input stream (needed for reading contents)
763 * will be <b>owned</b> (and managed, i.e. closed as need be) by
764 * the parser, since caller has no access to it.
765 *
766 * @param f File that contains JSON content to parse
Tatu Salorantafeaabd12012-07-22 23:03:41 -0700767 *
768 * @since 2.1
769 */
Tatu Saloranta32e4e912014-01-26 19:59:28 -0800770 public JsonParser createParser(File f) throws IOException, JsonParseException {
Tatu Salorantaf15531c2011-12-22 23:00:40 -0800771 // true, since we create InputStream from File
772 IOContext ctxt = _createContext(f, true);
773 InputStream in = new FileInputStream(f);
Tatu Saloranta896000f2014-04-19 12:53:40 -0700774 return _createParser(_decorate(in, ctxt), ctxt);
Tatu Salorantaf15531c2011-12-22 23:00:40 -0800775 }
776
777 /**
778 * Method for constructing JSON parser instance to parse
779 * contents of resource reference by given URL.
Dmitry Spikhalskiy5590fcf2015-11-29 20:27:14 +0300780 *
781 *<p>
782 * Encoding is auto-detected from contents according to JSON
783 * specification recommended mechanism. Json specification
784 * supports only UTF-8, UTF-16 and UTF-32 as valid encodings,
785 * so auto-detection implemented only for this charsets.
786 * For other charsets use {@link #createParser(java.io.Reader)}.
787 *
Tatu Salorantaf15531c2011-12-22 23:00:40 -0800788 *<p>
789 * Underlying input stream (needed for reading contents)
790 * will be <b>owned</b> (and managed, i.e. closed as need be) by
791 * the parser, since caller has no access to it.
792 *
793 * @param url URL pointing to resource that contains JSON content to parse
Tatu Saloranta68194922012-11-15 20:34:29 -0800794 *
795 * @since 2.1
Tatu Salorantaf15531c2011-12-22 23:00:40 -0800796 */
Tatu Saloranta32e4e912014-01-26 19:59:28 -0800797 public JsonParser createParser(URL url) throws IOException, JsonParseException {
Tatu Salorantaf15531c2011-12-22 23:00:40 -0800798 // true, since we create InputStream from URL
799 IOContext ctxt = _createContext(url, true);
800 InputStream in = _optimizedStreamFromURL(url);
Tatu Saloranta896000f2014-04-19 12:53:40 -0700801 return _createParser(_decorate(in, ctxt), ctxt);
Tatu Salorantaf15531c2011-12-22 23:00:40 -0800802 }
803
804 /**
805 * Method for constructing JSON parser instance to parse
806 * the contents accessed via specified input stream.
807 *<p>
808 * The input stream will <b>not be owned</b> by
809 * the parser, it will still be managed (i.e. closed if
810 * end-of-stream is reacher, or parser close method called)
811 * if (and only if) {@link com.fasterxml.jackson.core.JsonParser.Feature#AUTO_CLOSE_SOURCE}
812 * is enabled.
813 *<p>
Dmitry Spikhalskiy5590fcf2015-11-29 20:27:14 +0300814 *
Tatu Salorantaf15531c2011-12-22 23:00:40 -0800815 * Note: no encoding argument is taken since it can always be
Dmitry Spikhalskiy5590fcf2015-11-29 20:27:14 +0300816 * auto-detected as suggested by JSON RFC. Json specification
817 * supports only UTF-8, UTF-16 and UTF-32 as valid encodings,
818 * so auto-detection implemented only for this charsets.
819 * For other charsets use {@link #createParser(java.io.Reader)}.
Tatu Salorantaf15531c2011-12-22 23:00:40 -0800820 *
821 * @param in InputStream to use for reading JSON content to parse
Tatu Saloranta68194922012-11-15 20:34:29 -0800822 *
823 * @since 2.1
Tatu Salorantaf15531c2011-12-22 23:00:40 -0800824 */
Tatu Saloranta32e4e912014-01-26 19:59:28 -0800825 public JsonParser createParser(InputStream in) throws IOException, JsonParseException {
Tatu Salorantaf15531c2011-12-22 23:00:40 -0800826 IOContext ctxt = _createContext(in, false);
Tatu Saloranta896000f2014-04-19 12:53:40 -0700827 return _createParser(_decorate(in, ctxt), ctxt);
Tatu Salorantaf15531c2011-12-22 23:00:40 -0800828 }
Tatu Saloranta896000f2014-04-19 12:53:40 -0700829
Tatu Salorantaf15531c2011-12-22 23:00:40 -0800830 /**
831 * Method for constructing parser for parsing
832 * the contents accessed via specified Reader.
833 <p>
834 * The read stream will <b>not be owned</b> by
835 * the parser, it will still be managed (i.e. closed if
836 * end-of-stream is reacher, or parser close method called)
837 * if (and only if) {@link com.fasterxml.jackson.core.JsonParser.Feature#AUTO_CLOSE_SOURCE}
838 * is enabled.
Tatu Salorantaf15531c2011-12-22 23:00:40 -0800839 *
840 * @param r Reader to use for reading JSON content to parse
Tatu Saloranta68194922012-11-15 20:34:29 -0800841 *
842 * @since 2.1
Tatu Salorantaf15531c2011-12-22 23:00:40 -0800843 */
Tatu Saloranta32e4e912014-01-26 19:59:28 -0800844 public JsonParser createParser(Reader r) throws IOException, JsonParseException {
Tatu Salorantaf15531c2011-12-22 23:00:40 -0800845 // false -> we do NOT own Reader (did not create it)
846 IOContext ctxt = _createContext(r, false);
Tatu Saloranta896000f2014-04-19 12:53:40 -0700847 return _createParser(_decorate(r, ctxt), ctxt);
Tatu Salorantaf15531c2011-12-22 23:00:40 -0800848 }
849
850 /**
851 * Method for constructing parser for parsing
852 * the contents of given byte array.
Tatu Saloranta68194922012-11-15 20:34:29 -0800853 *
854 * @since 2.1
Tatu Salorantaf15531c2011-12-22 23:00:40 -0800855 */
Tatu Saloranta32e4e912014-01-26 19:59:28 -0800856 public JsonParser createParser(byte[] data) throws IOException, JsonParseException {
Tatu Salorantaf15531c2011-12-22 23:00:40 -0800857 IOContext ctxt = _createContext(data, true);
Tatu Salorantaf15531c2011-12-22 23:00:40 -0800858 if (_inputDecorator != null) {
859 InputStream in = _inputDecorator.decorate(ctxt, data, 0, data.length);
860 if (in != null) {
Tatu Salorantaeeb2fbd2012-05-28 22:00:08 -0700861 return _createParser(in, ctxt);
Tatu Salorantaf15531c2011-12-22 23:00:40 -0800862 }
863 }
Tatu Salorantaeeb2fbd2012-05-28 22:00:08 -0700864 return _createParser(data, 0, data.length, ctxt);
Tatu Salorantaf15531c2011-12-22 23:00:40 -0800865 }
866
867 /**
868 * Method for constructing parser for parsing
869 * the contents of given byte array.
870 *
871 * @param data Buffer that contains data to parse
872 * @param offset Offset of the first data byte within buffer
873 * @param len Length of contents to parse within buffer
Tatu Saloranta68194922012-11-15 20:34:29 -0800874 *
875 * @since 2.1
Tatu Salorantaf15531c2011-12-22 23:00:40 -0800876 */
Tatu Saloranta32e4e912014-01-26 19:59:28 -0800877 public JsonParser createParser(byte[] data, int offset, int len) throws IOException, JsonParseException {
Tatu Salorantaf15531c2011-12-22 23:00:40 -0800878 IOContext ctxt = _createContext(data, true);
879 // [JACKSON-512]: allow wrapping with InputDecorator
880 if (_inputDecorator != null) {
881 InputStream in = _inputDecorator.decorate(ctxt, data, offset, len);
882 if (in != null) {
Tatu Salorantaeeb2fbd2012-05-28 22:00:08 -0700883 return _createParser(in, ctxt);
Tatu Salorantaf15531c2011-12-22 23:00:40 -0800884 }
885 }
Tatu Saloranta68194922012-11-15 20:34:29 -0800886 return _createParser(data, offset, len, ctxt);
Tatu Salorantaf15531c2011-12-22 23:00:40 -0800887 }
888
889 /**
890 * Method for constructing parser for parsing
891 * contents of given String.
Tatu Saloranta68194922012-11-15 20:34:29 -0800892 *
893 * @since 2.1
Tatu Salorantaf15531c2011-12-22 23:00:40 -0800894 */
Tatu Saloranta32e4e912014-01-26 19:59:28 -0800895 public JsonParser createParser(String content) throws IOException, JsonParseException {
Tatu64aa9d22014-04-18 14:07:38 -0700896 final int strLen = content.length();
897 // Actually, let's use this for medium-sized content, up to 64kB chunk (32kb char)
Tatu Salorantad7cbb642016-05-13 13:23:04 -0700898 if ((_inputDecorator != null) || (strLen > 0x8000) || !canUseCharArrays()) {
Tatu64aa9d22014-04-18 14:07:38 -0700899 // easier to just wrap in a Reader than extend InputDecorator; or, if content
900 // is too long for us to copy it over
901 return createParser(new StringReader(content));
Tatu Salorantaf15531c2011-12-22 23:00:40 -0800902 }
Tatu64aa9d22014-04-18 14:07:38 -0700903 IOContext ctxt = _createContext(content, true);
Tatu Saloranta84dc1842014-04-18 21:07:57 -0700904 char[] buf = ctxt.allocTokenBuffer(strLen);
Tatu64aa9d22014-04-18 14:07:38 -0700905 content.getChars(0, strLen, buf, 0);
906 return _createParser(buf, 0, strLen, ctxt, true);
907 }
908
909 /**
910 * Method for constructing parser for parsing
911 * contents of given char array.
912 *
913 * @since 2.4
914 */
915 public JsonParser createParser(char[] content) throws IOException {
916 return createParser(content, 0, content.length);
917 }
918
919 /**
Tatu Saloranta896000f2014-04-19 12:53:40 -0700920 * Method for constructing parser for parsing contents of given char array.
Tatu64aa9d22014-04-18 14:07:38 -0700921 *
922 * @since 2.4
923 */
924 public JsonParser createParser(char[] content, int offset, int len) throws IOException {
925 if (_inputDecorator != null) { // easier to just wrap in a Reader than extend InputDecorator
926 return createParser(new CharArrayReader(content, offset, len));
927 }
Tatu Saloranta896000f2014-04-19 12:53:40 -0700928 return _createParser(content, offset, len, _createContext(content, true),
929 // important: buffer is NOT recyclable, as it's from caller
930 false);
Tatu Salorantaf15531c2011-12-22 23:00:40 -0800931 }
932
Tatu Salorantad7cbb642016-05-13 13:23:04 -0700933 /**
Tatu Saloranta81fb43c2017-05-17 18:25:34 -0700934 * Optional method for constructing parser for reading contents from specified {@link DataInput}
935 * instance.
936 *<p>
937 * If this factory does not support {@link DataInput} as source,
938 * will throw {@link UnsupportedOperationException}
939 *
Tatu Salorantad7cbb642016-05-13 13:23:04 -0700940 * @since 2.8
941 */
942 public JsonParser createParser(DataInput in) throws IOException {
943 IOContext ctxt = _createContext(in, false);
944 return _createParser(_decorate(in, ctxt), ctxt);
945 }
946
Tatu Salorantaf15531c2011-12-22 23:00:40 -0800947 /*
948 /**********************************************************
Tatu Saloranta81fb43c2017-05-17 18:25:34 -0700949 /* Parser factories, non-blocking (async) sources
950 /**********************************************************
951 */
952
953 /**
954 * Optional method for constructing parser for non-blocking parsing
955 * via {@link com.fasterxml.jackson.core.async.ByteArrayFeeder}
956 * interface (accessed using {@link JsonParser#getNonBlockingInputFeeder()}
957 * from constructed instance).
958 *<p>
959 * If this factory does not support non-blocking parsing (either at all,
960 * or from byte array),
961 * will throw {@link UnsupportedOperationException}
962 *
963 * @since 2.9
964 */
965 public JsonParser createNonBlockingByteArrayParser() throws IOException
966 {
967 // 17-May-2017, tatu: Need to take care not to accidentally create JSON parser
968 // for non-JSON input:
969 _requireJSONFactory("Non-blocking source not (yet?) support for this format (%s)");
970 IOContext ctxt = _createContext(null, false);
971 ByteQuadsCanonicalizer can = _byteSymbolCanonicalizer.makeChild(_factoryFeatures);
972 return new NonBlockingJsonParser(ctxt, _parserFeatures, can);
973 }
974
975 /*
976 /**********************************************************
Tatu Salorantad302ae02015-12-27 21:53:15 -0800977 /* Parser factories (old ones, pre-2.2)
Tatu Saloranta68194922012-11-15 20:34:29 -0800978 /**********************************************************
979 */
980
981 /**
982 * Method for constructing JSON parser instance to parse
Dmitry Spikhalskiy5590fcf2015-11-29 20:27:14 +0300983 * contents of specified file.
Dmitry Spikhalskiy5590fcf2015-11-29 20:27:14 +0300984 *<p>
985 * Encoding is auto-detected from contents according to JSON
986 * specification recommended mechanism. Json specification
987 * supports only UTF-8, UTF-16 and UTF-32 as valid encodings,
988 * so auto-detection implemented only for this charsets.
989 * For other charsets use {@link #createParser(java.io.Reader)}.
990 *
Tatu Saloranta68194922012-11-15 20:34:29 -0800991 *<p>
992 * Underlying input stream (needed for reading contents)
993 * will be <b>owned</b> (and managed, i.e. closed as need be) by
994 * the parser, since caller has no access to it.
Tatu Saloranta68194922012-11-15 20:34:29 -0800995 *
996 * @param f File that contains JSON content to parse
997 *
998 * @deprecated Since 2.2, use {@link #createParser(File)} instead.
999 */
1000 @Deprecated
Tatu Salorantaefc23672013-12-30 19:09:39 -08001001 public JsonParser createJsonParser(File f) throws IOException, JsonParseException {
Tatu Saloranta68194922012-11-15 20:34:29 -08001002 return createParser(f);
1003 }
1004
1005 /**
1006 * Method for constructing JSON parser instance to parse
1007 * contents of resource reference by given URL.
Dmitry Spikhalskiy5590fcf2015-11-29 20:27:14 +03001008 *
1009 *<p>
1010 * Encoding is auto-detected from contents according to JSON
1011 * specification recommended mechanism. Json specification
1012 * supports only UTF-8, UTF-16 and UTF-32 as valid encodings,
1013 * so auto-detection implemented only for this charsets.
1014 * For other charsets use {@link #createParser(java.io.Reader)}.
1015 *
Tatu Saloranta68194922012-11-15 20:34:29 -08001016 *<p>
1017 * Underlying input stream (needed for reading contents)
1018 * will be <b>owned</b> (and managed, i.e. closed as need be) by
1019 * the parser, since caller has no access to it.
Tatu Saloranta68194922012-11-15 20:34:29 -08001020 *
1021 * @param url URL pointing to resource that contains JSON content to parse
1022 *
1023 * @deprecated Since 2.2, use {@link #createParser(URL)} instead.
1024 */
1025 @Deprecated
Tatu Salorantaefc23672013-12-30 19:09:39 -08001026 public JsonParser createJsonParser(URL url) throws IOException, JsonParseException {
Tatu Saloranta68194922012-11-15 20:34:29 -08001027 return createParser(url);
1028 }
1029
1030 /**
1031 * Method for constructing JSON parser instance to parse
1032 * the contents accessed via specified input stream.
1033 *<p>
1034 * The input stream will <b>not be owned</b> by
1035 * the parser, it will still be managed (i.e. closed if
1036 * end-of-stream is reacher, or parser close method called)
1037 * if (and only if) {@link com.fasterxml.jackson.core.JsonParser.Feature#AUTO_CLOSE_SOURCE}
1038 * is enabled.
1039 *<p>
Dmitry Spikhalskiy5590fcf2015-11-29 20:27:14 +03001040 *
Tatu Saloranta68194922012-11-15 20:34:29 -08001041 * Note: no encoding argument is taken since it can always be
Dmitry Spikhalskiy5590fcf2015-11-29 20:27:14 +03001042 * auto-detected as suggested by JSON RFC. Json specification
1043 * supports only UTF-8, UTF-16 and UTF-32 as valid encodings,
1044 * so auto-detection implemented only for this charsets.
1045 * For other charsets use {@link #createParser(java.io.Reader)}.
Tatu Saloranta68194922012-11-15 20:34:29 -08001046 *
1047 * @param in InputStream to use for reading JSON content to parse
1048 *
1049 * @deprecated Since 2.2, use {@link #createParser(InputStream)} instead.
1050 */
1051 @Deprecated
Tatu Salorantaefc23672013-12-30 19:09:39 -08001052 public JsonParser createJsonParser(InputStream in) throws IOException, JsonParseException {
Tatu Saloranta68194922012-11-15 20:34:29 -08001053 return createParser(in);
1054 }
1055
1056 /**
1057 * Method for constructing parser for parsing
1058 * the contents accessed via specified Reader.
1059 <p>
1060 * The read stream will <b>not be owned</b> by
1061 * the parser, it will still be managed (i.e. closed if
1062 * end-of-stream is reacher, or parser close method called)
1063 * if (and only if) {@link com.fasterxml.jackson.core.JsonParser.Feature#AUTO_CLOSE_SOURCE}
1064 * is enabled.
Tatu Saloranta68194922012-11-15 20:34:29 -08001065 *
1066 * @param r Reader to use for reading JSON content to parse
1067 *
1068 * @deprecated Since 2.2, use {@link #createParser(Reader)} instead.
1069 */
1070 @Deprecated
Tatu Salorantaefc23672013-12-30 19:09:39 -08001071 public JsonParser createJsonParser(Reader r) throws IOException, JsonParseException {
Tatu Saloranta68194922012-11-15 20:34:29 -08001072 return createParser(r);
1073 }
1074
1075 /**
Tatu Salorantaefc23672013-12-30 19:09:39 -08001076 * Method for constructing parser for parsing the contents of given byte array.
Tatu Saloranta68194922012-11-15 20:34:29 -08001077 *
1078 * @deprecated Since 2.2, use {@link #createParser(byte[])} instead.
1079 */
1080 @Deprecated
Tatu Salorantaefc23672013-12-30 19:09:39 -08001081 public JsonParser createJsonParser(byte[] data) throws IOException, JsonParseException {
Tatu Saloranta68194922012-11-15 20:34:29 -08001082 return createParser(data);
1083 }
1084
1085 /**
1086 * Method for constructing parser for parsing
1087 * the contents of given byte array.
Tatu Saloranta68194922012-11-15 20:34:29 -08001088 *
1089 * @param data Buffer that contains data to parse
1090 * @param offset Offset of the first data byte within buffer
1091 * @param len Length of contents to parse within buffer
1092 *
1093 * @deprecated Since 2.2, use {@link #createParser(byte[],int,int)} instead.
1094 */
1095 @Deprecated
Tatu Salorantaefc23672013-12-30 19:09:39 -08001096 public JsonParser createJsonParser(byte[] data, int offset, int len) throws IOException, JsonParseException {
Tatu Saloranta68194922012-11-15 20:34:29 -08001097 return createParser(data, offset, len);
1098 }
1099
1100 /**
1101 * Method for constructing parser for parsing
1102 * contents of given String.
1103 *
1104 * @deprecated Since 2.2, use {@link #createParser(String)} instead.
1105 */
1106 @Deprecated
Tatu Salorantaefc23672013-12-30 19:09:39 -08001107 public JsonParser createJsonParser(String content) throws IOException, JsonParseException {
Tatu Saloranta68194922012-11-15 20:34:29 -08001108 return createParser(content);
1109 }
1110
1111 /*
1112 /**********************************************************
Tatu Salorantafeaabd12012-07-22 23:03:41 -07001113 /* Generator factories, new (as per [Issue-25]
Tatu Salorantaf15531c2011-12-22 23:00:40 -08001114 /**********************************************************
1115 */
1116
1117 /**
1118 * Method for constructing JSON generator for writing JSON content
1119 * using specified output stream.
1120 * Encoding to use must be specified, and needs to be one of available
1121 * types (as per JSON specification).
1122 *<p>
1123 * Underlying stream <b>is NOT owned</b> by the generator constructed,
1124 * so that generator will NOT close the output stream when
1125 * {@link JsonGenerator#close} is called (unless auto-closing
1126 * feature,
1127 * {@link com.fasterxml.jackson.core.JsonGenerator.Feature#AUTO_CLOSE_TARGET}
1128 * is enabled).
1129 * Using application needs to close it explicitly if this is the case.
1130 *<p>
1131 * Note: there are formats that use fixed encoding (like most binary data formats)
1132 * and that ignore passed in encoding.
Tatu Salorantafeaabd12012-07-22 23:03:41 -07001133 *
1134 * @param out OutputStream to use for writing JSON content
1135 * @param enc Character encoding to use
Tatu Saloranta4ab04ce2012-11-15 20:42:16 -08001136 *
1137 * @since 2.1
Tatu Salorantafeaabd12012-07-22 23:03:41 -07001138 */
1139 public JsonGenerator createGenerator(OutputStream out, JsonEncoding enc)
1140 throws IOException
1141 {
Tatu Saloranta4ab04ce2012-11-15 20:42:16 -08001142 // false -> we won't manage the stream unless explicitly directed to
1143 IOContext ctxt = _createContext(out, false);
1144 ctxt.setEncoding(enc);
1145 if (enc == JsonEncoding.UTF8) {
Tatu Saloranta896000f2014-04-19 12:53:40 -07001146 return _createUTF8Generator(_decorate(out, ctxt), ctxt);
Tatu Saloranta4ab04ce2012-11-15 20:42:16 -08001147 }
1148 Writer w = _createWriter(out, enc, ctxt);
Tatu Saloranta896000f2014-04-19 12:53:40 -07001149 return _createGenerator(_decorate(w, ctxt), ctxt);
Tatu Salorantafeaabd12012-07-22 23:03:41 -07001150 }
1151
1152 /**
Tatu Saloranta4ab04ce2012-11-15 20:42:16 -08001153 * Convenience method for constructing generator that uses default
1154 * encoding of the format (UTF-8 for JSON and most other data formats).
1155 *<p>
1156 * Note: there are formats that use fixed encoding (like most binary data formats).
1157 *
1158 * @since 2.1
1159 */
1160 public JsonGenerator createGenerator(OutputStream out) throws IOException {
1161 return createGenerator(out, JsonEncoding.UTF8);
1162 }
1163
1164 /**
Tatu Salorantafeaabd12012-07-22 23:03:41 -07001165 * Method for constructing JSON generator for writing JSON content
1166 * using specified Writer.
1167 *<p>
1168 * Underlying stream <b>is NOT owned</b> by the generator constructed,
1169 * so that generator will NOT close the Reader when
1170 * {@link JsonGenerator#close} is called (unless auto-closing
1171 * feature,
1172 * {@link com.fasterxml.jackson.core.JsonGenerator.Feature#AUTO_CLOSE_TARGET} is enabled).
1173 * Using application needs to close it explicitly.
Tatu Salorantafeaabd12012-07-22 23:03:41 -07001174 *
Tatu Saloranta4ab04ce2012-11-15 20:42:16 -08001175 * @since 2.1
Tatu Salorantafeaabd12012-07-22 23:03:41 -07001176 *
Tatu Saloranta896000f2014-04-19 12:53:40 -07001177 * @param w Writer to use for writing JSON content
Tatu Salorantafeaabd12012-07-22 23:03:41 -07001178 */
Tatu Saloranta896000f2014-04-19 12:53:40 -07001179 public JsonGenerator createGenerator(Writer w) throws IOException {
1180 IOContext ctxt = _createContext(w, false);
1181 return _createGenerator(_decorate(w, ctxt), ctxt);
Tatu Salorantafeaabd12012-07-22 23:03:41 -07001182 }
1183
1184 /**
1185 * Method for constructing JSON generator for writing JSON content
1186 * to specified file, overwriting contents it might have (or creating
1187 * it if such file does not yet exist).
1188 * Encoding to use must be specified, and needs to be one of available
1189 * types (as per JSON specification).
1190 *<p>
1191 * Underlying stream <b>is owned</b> by the generator constructed,
1192 * i.e. generator will handle closing of file when
1193 * {@link JsonGenerator#close} is called.
Tatu Salorantafeaabd12012-07-22 23:03:41 -07001194 *
1195 * @param f File to write contents to
1196 * @param enc Character encoding to use
Tatu Saloranta4ab04ce2012-11-15 20:42:16 -08001197 *
1198 * @since 2.1
Tatu Salorantafeaabd12012-07-22 23:03:41 -07001199 */
Tatu Salorantab0a2e192014-04-10 09:36:07 -07001200 public JsonGenerator createGenerator(File f, JsonEncoding enc) throws IOException
Tatu Salorantafeaabd12012-07-22 23:03:41 -07001201 {
Tatu Saloranta4ab04ce2012-11-15 20:42:16 -08001202 OutputStream out = new FileOutputStream(f);
1203 // true -> yes, we have to manage the stream since we created it
1204 IOContext ctxt = _createContext(out, true);
1205 ctxt.setEncoding(enc);
1206 if (enc == JsonEncoding.UTF8) {
Tatu Saloranta896000f2014-04-19 12:53:40 -07001207 return _createUTF8Generator(_decorate(out, ctxt), ctxt);
Tatu Saloranta4ab04ce2012-11-15 20:42:16 -08001208 }
1209 Writer w = _createWriter(out, enc, ctxt);
Tatu Saloranta896000f2014-04-19 12:53:40 -07001210 return _createGenerator(_decorate(w, ctxt), ctxt);
Tatu Salorantafeaabd12012-07-22 23:03:41 -07001211 }
1212
Tatu Saloranta38b3ef12016-05-03 18:08:31 -07001213 /**
1214 * Method for constructing generator for writing content using specified
1215 * {@link DataOutput} instance.
1216 *
1217 * @since 2.8
1218 */
1219 public JsonGenerator createGenerator(DataOutput out, JsonEncoding enc) throws IOException {
1220 return createGenerator(_createDataOutputWrapper(out), enc);
1221 }
1222
1223 /**
1224 * Convenience method for constructing generator that uses default
1225 * encoding of the format (UTF-8 for JSON and most other data formats).
1226 *<p>
1227 * Note: there are formats that use fixed encoding (like most binary data formats).
1228 *
1229 * @since 2.8
1230 */
1231 public JsonGenerator createGenerator(DataOutput out) throws IOException {
1232 return createGenerator(_createDataOutputWrapper(out), JsonEncoding.UTF8);
1233 }
1234
Tatu Salorantafeaabd12012-07-22 23:03:41 -07001235 /*
1236 /**********************************************************
Tatu Salorantad302ae02015-12-27 21:53:15 -08001237 /* Generator factories, old (pre-2.2)
Tatu Salorantafeaabd12012-07-22 23:03:41 -07001238 /**********************************************************
1239 */
1240
1241 /**
1242 * Method for constructing JSON generator for writing JSON content
1243 * using specified output stream.
1244 * Encoding to use must be specified, and needs to be one of available
1245 * types (as per JSON specification).
1246 *<p>
1247 * Underlying stream <b>is NOT owned</b> by the generator constructed,
1248 * so that generator will NOT close the output stream when
1249 * {@link JsonGenerator#close} is called (unless auto-closing
1250 * feature,
1251 * {@link com.fasterxml.jackson.core.JsonGenerator.Feature#AUTO_CLOSE_TARGET}
1252 * is enabled).
1253 * Using application needs to close it explicitly if this is the case.
1254 *<p>
1255 * Note: there are formats that use fixed encoding (like most binary data formats)
1256 * and that ignore passed in encoding.
Tatu Salorantaf15531c2011-12-22 23:00:40 -08001257 *
1258 * @param out OutputStream to use for writing JSON content
1259 * @param enc Character encoding to use
Tatu Saloranta4ab04ce2012-11-15 20:42:16 -08001260 *
1261 * @deprecated Since 2.2, use {@link #createGenerator(OutputStream, JsonEncoding)} instead.
Tatu Salorantaf15531c2011-12-22 23:00:40 -08001262 */
Tatu Saloranta4ab04ce2012-11-15 20:42:16 -08001263 @Deprecated
Tatu Salorantab0a2e192014-04-10 09:36:07 -07001264 public JsonGenerator createJsonGenerator(OutputStream out, JsonEncoding enc) throws IOException {
Tatu Saloranta4ab04ce2012-11-15 20:42:16 -08001265 return createGenerator(out, enc);
Tatu Salorantaf15531c2011-12-22 23:00:40 -08001266 }
1267
1268 /**
1269 * Method for constructing JSON generator for writing JSON content
1270 * using specified Writer.
1271 *<p>
1272 * Underlying stream <b>is NOT owned</b> by the generator constructed,
1273 * so that generator will NOT close the Reader when
1274 * {@link JsonGenerator#close} is called (unless auto-closing
1275 * feature,
1276 * {@link com.fasterxml.jackson.core.JsonGenerator.Feature#AUTO_CLOSE_TARGET} is enabled).
1277 * Using application needs to close it explicitly.
1278 *
1279 * @param out Writer to use for writing JSON content
Tatu Saloranta4ab04ce2012-11-15 20:42:16 -08001280 *
1281 * @deprecated Since 2.2, use {@link #createGenerator(Writer)} instead.
Tatu Salorantaf15531c2011-12-22 23:00:40 -08001282 */
Tatu Saloranta4ab04ce2012-11-15 20:42:16 -08001283 @Deprecated
Tatu Salorantab0a2e192014-04-10 09:36:07 -07001284 public JsonGenerator createJsonGenerator(Writer out) throws IOException {
Tatu Saloranta4ab04ce2012-11-15 20:42:16 -08001285 return createGenerator(out);
Tatu Salorantaf15531c2011-12-22 23:00:40 -08001286 }
1287
1288 /**
1289 * Convenience method for constructing generator that uses default
1290 * encoding of the format (UTF-8 for JSON and most other data formats).
1291 *<p>
1292 * Note: there are formats that use fixed encoding (like most binary data formats).
Tatu Saloranta4ab04ce2012-11-15 20:42:16 -08001293 *
1294 * @deprecated Since 2.2, use {@link #createGenerator(OutputStream)} instead.
Tatu Salorantaf15531c2011-12-22 23:00:40 -08001295 */
Tatu Saloranta4ab04ce2012-11-15 20:42:16 -08001296 @Deprecated
Tatu Salorantaf15531c2011-12-22 23:00:40 -08001297 public JsonGenerator createJsonGenerator(OutputStream out) throws IOException {
Tatu Saloranta4ab04ce2012-11-15 20:42:16 -08001298 return createGenerator(out, JsonEncoding.UTF8);
Tatu Salorantaf15531c2011-12-22 23:00:40 -08001299 }
Tatu Salorantaf15531c2011-12-22 23:00:40 -08001300
1301 /*
1302 /**********************************************************
1303 /* Factory methods used by factory for creating parser instances,
1304 /* overridable by sub-classes
1305 /**********************************************************
1306 */
1307
1308 /**
1309 * Overridable factory method that actually instantiates desired parser
1310 * given {@link InputStream} and context object.
1311 *<p>
1312 * This method is specifically designed to remain
1313 * compatible between minor versions so that sub-classes can count
1314 * on it being called as expected. That is, it is part of official
1315 * interface from sub-class perspective, although not a public
1316 * method available to users of factory implementations.
Tatu Salorantaeeb2fbd2012-05-28 22:00:08 -07001317 *
1318 * @since 2.1
Tatu Salorantaf15531c2011-12-22 23:00:40 -08001319 */
Tatu Salorantab0a2e192014-04-10 09:36:07 -07001320 protected JsonParser _createParser(InputStream in, IOContext ctxt) throws IOException {
Tatu Saloranta68194922012-11-15 20:34:29 -08001321 // As per [JACKSON-259], may want to fully disable canonicalization:
1322 return new ByteSourceJsonBootstrapper(ctxt, in).constructParser(_parserFeatures,
Tatu Salorantadccffbe2015-02-05 21:17:57 -08001323 _objectCodec, _byteSymbolCanonicalizer, _rootCharSymbols, _factoryFeatures);
Tatu Salorantaeeb2fbd2012-05-28 22:00:08 -07001324 }
1325
1326 /**
Tatu Salorantaf15531c2011-12-22 23:00:40 -08001327 * Overridable factory method that actually instantiates parser
1328 * using given {@link Reader} object for reading content.
1329 *<p>
1330 * This method is specifically designed to remain
1331 * compatible between minor versions so that sub-classes can count
1332 * on it being called as expected. That is, it is part of official
1333 * interface from sub-class perspective, although not a public
1334 * method available to users of factory implementations.
Tatu Salorantaeeb2fbd2012-05-28 22:00:08 -07001335 *
1336 * @since 2.1
Tatu Salorantaf15531c2011-12-22 23:00:40 -08001337 */
Tatu Salorantab0a2e192014-04-10 09:36:07 -07001338 protected JsonParser _createParser(Reader r, IOContext ctxt) throws IOException {
Tatu Saloranta68194922012-11-15 20:34:29 -08001339 return new ReaderBasedJsonParser(ctxt, _parserFeatures, r, _objectCodec,
Tatu Saloranta0541b3b2014-05-23 20:20:46 -07001340 _rootCharSymbols.makeChild(_factoryFeatures));
Tatu Salorantaeeb2fbd2012-05-28 22:00:08 -07001341 }
1342
1343 /**
Tatu Salorantaf15531c2011-12-22 23:00:40 -08001344 * Overridable factory method that actually instantiates parser
Tatu64aa9d22014-04-18 14:07:38 -07001345 * using given <code>char[]</code> object for accessing content.
1346 *
1347 * @since 2.4
1348 */
1349 protected JsonParser _createParser(char[] data, int offset, int len, IOContext ctxt,
1350 boolean recyclable) throws IOException {
1351 return new ReaderBasedJsonParser(ctxt, _parserFeatures, null, _objectCodec,
Tatu Saloranta0541b3b2014-05-23 20:20:46 -07001352 _rootCharSymbols.makeChild(_factoryFeatures),
1353 data, offset, offset+len, recyclable);
Tatu64aa9d22014-04-18 14:07:38 -07001354 }
1355
1356 /**
1357 * Overridable factory method that actually instantiates parser
Tatu Salorantaf15531c2011-12-22 23:00:40 -08001358 * using given {@link Reader} object for reading content
1359 * passed as raw byte array.
1360 *<p>
1361 * This method is specifically designed to remain
1362 * compatible between minor versions so that sub-classes can count
1363 * on it being called as expected. That is, it is part of official
1364 * interface from sub-class perspective, although not a public
1365 * method available to users of factory implementations.
1366 */
Tatu64aa9d22014-04-18 14:07:38 -07001367 protected JsonParser _createParser(byte[] data, int offset, int len, IOContext ctxt) throws IOException
Tatu Salorantaf15531c2011-12-22 23:00:40 -08001368 {
Tatu Saloranta68194922012-11-15 20:34:29 -08001369 return new ByteSourceJsonBootstrapper(ctxt, data, offset, len).constructParser(_parserFeatures,
Tatu Salorantadccffbe2015-02-05 21:17:57 -08001370 _objectCodec, _byteSymbolCanonicalizer, _rootCharSymbols, _factoryFeatures);
Tatu Salorantaeeb2fbd2012-05-28 22:00:08 -07001371 }
1372
Tatu Salorantad7cbb642016-05-13 13:23:04 -07001373 /**
Tatu Saloranta81fb43c2017-05-17 18:25:34 -07001374 * Optional factory method, expected to be overridden
1375 *
Tatu Salorantad7cbb642016-05-13 13:23:04 -07001376 * @since 2.8
1377 */
1378 protected JsonParser _createParser(DataInput input, IOContext ctxt) throws IOException
1379 {
1380 // 13-May-2016, tatu: Need to take care not to accidentally create JSON parser for
Tatu Saloranta81fb43c2017-05-17 18:25:34 -07001381 // non-JSON input.
1382 _requireJSONFactory("InputData source not (yet?) support for this format (%s)");
Tatu Saloranta155babc2016-05-17 16:13:19 -07001383 // Also: while we can't do full bootstrapping (due to read-ahead limitations), should
1384 // at least handle possible UTF-8 BOM
1385 int firstByte = ByteSourceJsonBootstrapper.skipUTF8BOM(input);
Tatu Salorantad7cbb642016-05-13 13:23:04 -07001386 ByteQuadsCanonicalizer can = _byteSymbolCanonicalizer.makeChild(_factoryFeatures);
1387 return new UTF8DataInputJsonParser(ctxt, _parserFeatures, input,
Tatu Saloranta155babc2016-05-17 16:13:19 -07001388 _objectCodec, can, firstByte);
Tatu Salorantad7cbb642016-05-13 13:23:04 -07001389 }
1390
Tatu Salorantaf15531c2011-12-22 23:00:40 -08001391 /*
1392 /**********************************************************
1393 /* Factory methods used by factory for creating generator instances,
1394 /* overridable by sub-classes
1395 /**********************************************************
1396 */
1397
1398 /**
1399 * Overridable factory method that actually instantiates generator for
1400 * given {@link Writer} and context object.
1401 *<p>
1402 * This method is specifically designed to remain
1403 * compatible between minor versions so that sub-classes can count
1404 * on it being called as expected. That is, it is part of official
1405 * interface from sub-class perspective, although not a public
1406 * method available to users of factory implementations.
1407 */
Tatu Salorantaefc23672013-12-30 19:09:39 -08001408 protected JsonGenerator _createGenerator(Writer out, IOContext ctxt) throws IOException
Tatu Salorantaeeb2fbd2012-05-28 22:00:08 -07001409 {
Tatu Salorantae6dfc692012-09-28 15:34:05 -07001410 WriterBasedJsonGenerator gen = new WriterBasedJsonGenerator(ctxt,
1411 _generatorFeatures, _objectCodec, out);
Tatu Salorantaf15531c2011-12-22 23:00:40 -08001412 if (_characterEscapes != null) {
1413 gen.setCharacterEscapes(_characterEscapes);
1414 }
Tatu Salorantae6dfc692012-09-28 15:34:05 -07001415 SerializableString rootSep = _rootValueSeparator;
1416 if (rootSep != DEFAULT_ROOT_VALUE_SEPARATOR) {
1417 gen.setRootValueSeparator(rootSep);
1418 }
Tatu Salorantaf15531c2011-12-22 23:00:40 -08001419 return gen;
1420 }
1421
1422 /**
1423 * Overridable factory method that actually instantiates generator for
1424 * given {@link OutputStream} and context object, using UTF-8 encoding.
1425 *<p>
1426 * This method is specifically designed to remain
1427 * compatible between minor versions so that sub-classes can count
1428 * on it being called as expected. That is, it is part of official
1429 * interface from sub-class perspective, although not a public
1430 * method available to users of factory implementations.
1431 */
Tatu Salorantaeeb2fbd2012-05-28 22:00:08 -07001432 protected JsonGenerator _createUTF8Generator(OutputStream out, IOContext ctxt) throws IOException {
Tatu Salorantae6dfc692012-09-28 15:34:05 -07001433 UTF8JsonGenerator gen = new UTF8JsonGenerator(ctxt,
1434 _generatorFeatures, _objectCodec, out);
Tatu Salorantaf15531c2011-12-22 23:00:40 -08001435 if (_characterEscapes != null) {
1436 gen.setCharacterEscapes(_characterEscapes);
1437 }
Tatu Salorantae6dfc692012-09-28 15:34:05 -07001438 SerializableString rootSep = _rootValueSeparator;
1439 if (rootSep != DEFAULT_ROOT_VALUE_SEPARATOR) {
1440 gen.setRootValueSeparator(rootSep);
1441 }
Tatu Salorantaf15531c2011-12-22 23:00:40 -08001442 return gen;
1443 }
1444
Tatu Salorantaf15531c2011-12-22 23:00:40 -08001445 protected Writer _createWriter(OutputStream out, JsonEncoding enc, IOContext ctxt) throws IOException
1446 {
1447 // note: this should not get called any more (caller checks, dispatches)
1448 if (enc == JsonEncoding.UTF8) { // We have optimized writer for UTF-8
1449 return new UTF8Writer(ctxt, out);
1450 }
1451 // not optimal, but should do unless we really care about UTF-16/32 encoding speed
1452 return new OutputStreamWriter(out, enc.getJavaName());
1453 }
Tatu Saloranta896000f2014-04-19 12:53:40 -07001454
1455 /*
1456 /**********************************************************
1457 /* Internal factory methods, decorator handling
1458 /**********************************************************
1459 */
1460
1461 /**
1462 * @since 2.4
1463 */
1464 protected final InputStream _decorate(InputStream in, IOContext ctxt) throws IOException {
1465 if (_inputDecorator != null) {
1466 InputStream in2 = _inputDecorator.decorate(ctxt, in);
1467 if (in2 != null) {
1468 return in2;
1469 }
1470 }
1471 return in;
1472 }
Tatu Salorantad7cbb642016-05-13 13:23:04 -07001473
Tatu Saloranta896000f2014-04-19 12:53:40 -07001474 /**
1475 * @since 2.4
1476 */
1477 protected final Reader _decorate(Reader in, IOContext ctxt) throws IOException {
1478 if (_inputDecorator != null) {
1479 Reader in2 = _inputDecorator.decorate(ctxt, in);
1480 if (in2 != null) {
1481 return in2;
1482 }
1483 }
1484 return in;
1485 }
1486
1487 /**
Tatu Salorantad7cbb642016-05-13 13:23:04 -07001488 * @since 2.8
1489 */
1490 protected final DataInput _decorate(DataInput in, IOContext ctxt) throws IOException {
1491 if (_inputDecorator != null) {
1492 DataInput in2 = _inputDecorator.decorate(ctxt, in);
1493 if (in2 != null) {
1494 return in2;
1495 }
1496 }
1497 return in;
1498 }
1499
1500 /**
Tatu Saloranta896000f2014-04-19 12:53:40 -07001501 * @since 2.4
1502 */
1503 protected final OutputStream _decorate(OutputStream out, IOContext ctxt) throws IOException {
1504 if (_outputDecorator != null) {
1505 OutputStream out2 = _outputDecorator.decorate(ctxt, out);
1506 if (out2 != null) {
1507 return out2;
1508 }
1509 }
1510 return out;
1511 }
1512
1513 /**
1514 * @since 2.4
1515 */
1516 protected final Writer _decorate(Writer out, IOContext ctxt) throws IOException {
1517 if (_outputDecorator != null) {
1518 Writer out2 = _outputDecorator.decorate(ctxt, out);
1519 if (out2 != null) {
1520 return out2;
1521 }
1522 }
1523 return out;
1524 }
Tatu Salorantaf15531c2011-12-22 23:00:40 -08001525
1526 /*
1527 /**********************************************************
1528 /* Internal factory methods, other
1529 /**********************************************************
1530 */
1531
1532 /**
Tatu Salorantaf15531c2011-12-22 23:00:40 -08001533 * Method used by factory to create buffer recycler instances
1534 * for parsers and generators.
1535 *<p>
1536 * Note: only public to give access for <code>ObjectMapper</code>
1537 */
1538 public BufferRecycler _getBufferRecycler()
1539 {
Tatu Saloranta8891c0c2015-04-23 22:47:05 -07001540 /* 23-Apr-2015, tatu: Let's allow disabling of buffer recycling
1541 * scheme, for cases where it is considered harmful (possibly
1542 * on Android, for example)
1543 */
Tatu Salorantaddec51c2017-02-28 16:07:04 -08001544 if (Feature.USE_THREAD_LOCAL_FOR_BUFFER_RECYCLING.enabledIn(_factoryFeatures)) {
Tatu Saloranta8891c0c2015-04-23 22:47:05 -07001545 SoftReference<BufferRecycler> ref = _recyclerRef.get();
happyelf833de412016-07-23 11:10:21 +08001546 BufferRecycler br = (ref == null) ? null : ref.get();
Tatu Saloranta8891c0c2015-04-23 22:47:05 -07001547
1548 if (br == null) {
1549 br = new BufferRecycler();
1550 _recyclerRef.set(new SoftReference<BufferRecycler>(br));
1551 }
happyelf833de412016-07-23 11:10:21 +08001552 return br;
Tatu Salorantaf15531c2011-12-22 23:00:40 -08001553 }
happyelf833de412016-07-23 11:10:21 +08001554 return new BufferRecycler();
Tatu Salorantaf15531c2011-12-22 23:00:40 -08001555 }
Tatu Salorantad302ae02015-12-27 21:53:15 -08001556
Tatu Salorantaf15531c2011-12-22 23:00:40 -08001557 /**
Tatu Saloranta896000f2014-04-19 12:53:40 -07001558 * Overridable factory method that actually instantiates desired
1559 * context object.
1560 */
1561 protected IOContext _createContext(Object srcRef, boolean resourceManaged) {
1562 return new IOContext(_getBufferRecycler(), srcRef, resourceManaged);
1563 }
Tatu Salorantad302ae02015-12-27 21:53:15 -08001564
Tatu Saloranta896000f2014-04-19 12:53:40 -07001565 /**
Tatu Saloranta38b3ef12016-05-03 18:08:31 -07001566 * @since 2.8
1567 */
1568 protected OutputStream _createDataOutputWrapper(DataOutput out) {
1569 return new DataOutputAsStream(out);
1570 }
1571
1572 /**
Tatu Salorantaf15531c2011-12-22 23:00:40 -08001573 * Helper methods used for constructing an optimal stream for
1574 * parsers to use, when input is to be read from an URL.
1575 * This helps when reading file content via URL.
1576 */
Tatu Salorantaefc23672013-12-30 19:09:39 -08001577 protected InputStream _optimizedStreamFromURL(URL url) throws IOException {
Tatu Salorantaf15531c2011-12-22 23:00:40 -08001578 if ("file".equals(url.getProtocol())) {
1579 /* Can not do this if the path refers
1580 * to a network drive on windows. This fixes the problem;
1581 * might not be needed on all platforms (NFS?), but should not
1582 * matter a lot: performance penalty of extra wrapping is more
1583 * relevant when accessing local file system.
1584 */
1585 String host = url.getHost();
1586 if (host == null || host.length() == 0) {
Tatu Saloranta38b3ef12016-05-03 18:08:31 -07001587 // [core#48]: Let's try to avoid probs with URL encoded stuff
Tatu Saloranta61d5bdd2013-01-11 19:02:01 -08001588 String path = url.getPath();
1589 if (path.indexOf('%') < 0) {
1590 return new FileInputStream(url.getPath());
1591
1592 }
1593 // otherwise, let's fall through and let URL decoder do its magic
Tatu Salorantaf15531c2011-12-22 23:00:40 -08001594 }
1595 }
1596 return url.openStream();
1597 }
Tatu Saloranta81fb43c2017-05-17 18:25:34 -07001598
1599 /*
1600 /**********************************************************
1601 /* Internal helper methods
1602 /**********************************************************
1603 */
1604
1605 /**
1606 * Helper method called to work around the problem of this class both defining
1607 * general API for constructing parsers+generators AND implementing the API
1608 * for JSON handling. Problem here is that when adding new functionality
1609 * via factory methods, it is not possible to leave these methods abstract
1610 * (because we are implementing them for JSON); but there is risk that
1611 * sub-classes do not override them all (plus older version can not implement).
1612 * So a work-around is to add a check to ensure that factory is still one
1613 * used for JSON; and if not, make base implementation of a factory method fail.
1614 *
1615 * @since 2.9
1616 */
1617 private final void _requireJSONFactory(String msg) {
Tatu Saloranta89986a82017-06-01 00:01:38 -07001618 if (!_isJSONFactory()) {
1619 throw new UnsupportedOperationException(String.format(msg, getFormatName()));
1620 }
1621 }
1622
1623 private final boolean _isJSONFactory() {
Tatu Saloranta81fb43c2017-05-17 18:25:34 -07001624 // NOTE: since we only really care about whether this is standard JSON-backed factory,
1625 // or its sub-class / delegated to one, no need to check for equality, identity is enough
Tatu Saloranta89986a82017-06-01 00:01:38 -07001626 return getFormatName() == FORMAT_NAME_JSON;
Tatu Saloranta81fb43c2017-05-17 18:25:34 -07001627 }
Tatu Salorantaf15531c2011-12-22 23:00:40 -08001628}