blob: 02de2b02c876a5f3aa693d02cff3f9eb1adcfdc3 [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 Salorantaf15531c2011-12-22 23:00:40 -080015import com.fasterxml.jackson.core.sym.BytesToNameCanonicalizer;
16import com.fasterxml.jackson.core.sym.CharsToNameCanonicalizer;
17import com.fasterxml.jackson.core.util.BufferRecycler;
Tatu Salorantae6dfc692012-09-28 15:34:05 -070018import com.fasterxml.jackson.core.util.DefaultPrettyPrinter;
Tatu Salorantaf15531c2011-12-22 23:00:40 -080019
20/**
21 * The main factory class of Jackson package, used to configure and
22 * construct reader (aka parser, {@link JsonParser})
23 * and writer (aka generator, {@link JsonGenerator})
24 * instances.
25 *<p>
26 * Factory instances are thread-safe and reusable after configuration
27 * (if any). Typically applications and services use only a single
28 * globally shared factory instance, unless they need differently
29 * configured factories. Factory reuse is important if efficiency matters;
30 * most recycling of expensive construct is done on per-factory basis.
31 *<p>
32 * Creation of a factory instance is a light-weight operation,
33 * and since there is no need for pluggable alternative implementations
34 * (as there is no "standard" JSON processor API to implement),
35 * the default constructor is used for constructing factory
36 * instances.
37 *
38 * @author Tatu Saloranta
39 */
Tatu Salorantae92d04f2013-07-24 22:58:08 -070040@SuppressWarnings("resource")
Tatu Saloranta95f76a42012-10-05 13:04:23 -070041public class JsonFactory
42 implements Versioned,
43 java.io.Serializable // since 2.1 (for Android, mostly)
Tatu Salorantaf15531c2011-12-22 23:00:40 -080044{
45 /**
Tatu Salorantae92d04f2013-07-24 22:58:08 -070046 * Computed for Jackson 2.3.0 release
Tatu Saloranta95f76a42012-10-05 13:04:23 -070047 */
Tatu Salorantae92d04f2013-07-24 22:58:08 -070048 private static final long serialVersionUID = 3194418244231611666L;
Tatu Saloranta95f76a42012-10-05 13:04:23 -070049
Tatu Saloranta7b796a82013-04-27 10:18:30 -070050 /*
51 /**********************************************************
52 /* Helper types
53 /**********************************************************
Tatu Salorantaf15531c2011-12-22 23:00:40 -080054 */
Tatu Salorantae92d04f2013-07-24 22:58:08 -070055
Tatu07351902012-01-19 13:12:13 -080056 /**
57 * Enumeration that defines all on/off features that can only be
58 * changed for {@link JsonFactory}.
59 */
60 public enum Feature {
61
62 // // // Symbol handling (interning etc)
63
64 /**
65 * Feature that determines whether JSON object field names are
66 * to be canonicalized using {@link String#intern} or not:
67 * if enabled, all field names will be intern()ed (and caller
68 * can count on this being true for all such names); if disabled,
69 * no intern()ing is done. There may still be basic
70 * canonicalization (that is, same String will be used to represent
71 * all identical object property names for a single document).
72 *<p>
73 * Note: this setting only has effect if
74 * {@link #CANONICALIZE_FIELD_NAMES} is true -- otherwise no
75 * canonicalization of any sort is done.
76 *<p>
77 * This setting is enabled by default.
78 */
79 INTERN_FIELD_NAMES(true),
80
81 /**
82 * Feature that determines whether JSON object field names are
83 * to be canonicalized (details of how canonicalization is done
84 * then further specified by
85 * {@link #INTERN_FIELD_NAMES}).
86 *<p>
87 * This setting is enabled by default.
88 */
89 CANONICALIZE_FIELD_NAMES(true)
90
91 ;
92
93 /**
94 * Whether feature is enabled or disabled by default.
95 */
96 private final boolean _defaultState;
97
98 /**
99 * Method that calculates bit set (flags) of all features that
100 * are enabled by default.
101 */
102 public static int collectDefaults()
103 {
104 int flags = 0;
105 for (Feature f : values()) {
106 if (f.enabledByDefault()) {
107 flags |= f.getMask();
108 }
109 }
110 return flags;
111 }
112
113 private Feature(boolean defaultState)
114 {
115 _defaultState = defaultState;
116 }
117
118 public boolean enabledByDefault() { return _defaultState; }
119
120 public boolean enabledIn(int flags) { return (flags & getMask()) != 0; }
121
122 public int getMask() { return (1 << ordinal()); }
Tatu Saloranta7b796a82013-04-27 10:18:30 -0700123 }
124
125 /*
126 /**********************************************************
127 /* Constants
128 /**********************************************************
129 */
130
131 /**
132 * Name used to identify JSON format
133 * (and returned by {@link #getFormatName()}
134 */
135 public final static String FORMAT_NAME_JSON = "JSON";
136
137 /**
138 * Bitfield (set of flags) of all factory features that are enabled by default.
139 */
140 protected final static int DEFAULT_FACTORY_FEATURE_FLAGS = JsonFactory.Feature.collectDefaults();
141
142 /**
143 * Bitfield (set of flags) of all parser features that are enabled
144 * by default.
145 */
146 protected final static int DEFAULT_PARSER_FEATURE_FLAGS = JsonParser.Feature.collectDefaults();
147
148 /**
149 * Bitfield (set of flags) of all generator features that are enabled
150 * by default.
151 */
152 protected final static int DEFAULT_GENERATOR_FEATURE_FLAGS = JsonGenerator.Feature.collectDefaults();
153
154 private final static SerializableString DEFAULT_ROOT_VALUE_SEPARATOR = DefaultPrettyPrinter.DEFAULT_ROOT_VALUE_SEPARATOR;
155
Tatu Salorantaf15531c2011-12-22 23:00:40 -0800156 /*
157 /**********************************************************
158 /* Buffer, symbol table management
159 /**********************************************************
160 */
161
162 /**
Tatu Saloranta10c3ec82012-09-05 19:38:49 -0700163 * This <code>ThreadLocal</code> contains a {@link java.lang.ref.SoftReference}
Tatu Salorantaf15531c2011-12-22 23:00:40 -0800164 * to a {@link BufferRecycler} used to provide a low-cost
165 * buffer recycling between reader and writer instances.
166 */
167 final protected static ThreadLocal<SoftReference<BufferRecycler>> _recyclerRef
168 = new ThreadLocal<SoftReference<BufferRecycler>>();
169
170 /**
171 * Each factory comes equipped with a shared root symbol table.
172 * It should not be linked back to the original blueprint, to
173 * avoid contents from leaking between factories.
174 */
Tatu Saloranta95f76a42012-10-05 13:04:23 -0700175 protected final transient CharsToNameCanonicalizer _rootCharSymbols = CharsToNameCanonicalizer.createRoot();
Tatu Salorantaf15531c2011-12-22 23:00:40 -0800176
177 /**
178 * Alternative to the basic symbol table, some stream-based
179 * parsers use different name canonicalization method.
180 *<p>
181 * TODO: should clean up this; looks messy having 2 alternatives
182 * with not very clear differences.
183 */
Tatu Saloranta95f76a42012-10-05 13:04:23 -0700184 protected final transient BytesToNameCanonicalizer _rootByteSymbols = BytesToNameCanonicalizer.createRoot();
Tatu Salorantaf15531c2011-12-22 23:00:40 -0800185
186 /*
187 /**********************************************************
188 /* Configuration
189 /**********************************************************
190 */
191
192 /**
193 * Object that implements conversion functionality between
194 * Java objects and JSON content. For base JsonFactory implementation
195 * usually not set by default, but can be explicitly set.
196 * Sub-classes (like @link org.codehaus.jackson.map.MappingJsonFactory}
197 * usually provide an implementation.
198 */
199 protected ObjectCodec _objectCodec;
200
201 /**
Tatu07351902012-01-19 13:12:13 -0800202 * Currently enabled factory features.
203 */
204 protected int _factoryFeatures = DEFAULT_FACTORY_FEATURE_FLAGS;
205
206 /**
Tatu Salorantaf15531c2011-12-22 23:00:40 -0800207 * Currently enabled parser features.
208 */
209 protected int _parserFeatures = DEFAULT_PARSER_FEATURE_FLAGS;
210
211 /**
212 * Currently enabled generator features.
213 */
214 protected int _generatorFeatures = DEFAULT_GENERATOR_FEATURE_FLAGS;
215
216 /**
217 * Definition of custom character escapes to use for generators created
218 * by this factory, if any. If null, standard data format specific
219 * escapes are used.
220 */
221 protected CharacterEscapes _characterEscapes;
222
223 /**
224 * Optional helper object that may decorate input sources, to do
225 * additional processing on input during parsing.
226 */
227 protected InputDecorator _inputDecorator;
228
229 /**
230 * Optional helper object that may decorate output object, to do
231 * additional processing on output during content generation.
232 */
233 protected OutputDecorator _outputDecorator;
Tatu Salorantae6dfc692012-09-28 15:34:05 -0700234
235 /**
236 * Separator used between root-level values, if any; null indicates
237 * "do not add separator".
238 * Default separator is a single space character.
239 *
240 * @since 2.1
241 */
242 protected SerializableString _rootValueSeparator = DEFAULT_ROOT_VALUE_SEPARATOR;
Tatu Salorantaf15531c2011-12-22 23:00:40 -0800243
244 /*
245 /**********************************************************
246 /* Construction
247 /**********************************************************
248 */
249
250 /**
251 * Default constructor used to create factory instances.
252 * Creation of a factory instance is a light-weight operation,
253 * but it is still a good idea to reuse limited number of
254 * factory instances (and quite often just a single instance):
255 * factories are used as context for storing some reused
256 * processing objects (such as symbol tables parsers use)
257 * and this reuse only works within context of a single
258 * factory instance.
259 */
Tatu Saloranta7b796a82013-04-27 10:18:30 -0700260 public JsonFactory() { this((ObjectCodec) null); }
Tatu Salorantaf15531c2011-12-22 23:00:40 -0800261
262 public JsonFactory(ObjectCodec oc) { _objectCodec = oc; }
263
Tatu Saloranta378ecdc2012-08-04 16:27:27 -0700264 /**
Tatu Saloranta7b796a82013-04-27 10:18:30 -0700265 * Constructor used when copy()ing a factory instance.
266 *
267 * @since 2.2.1
268 */
269 protected JsonFactory(JsonFactory src, ObjectCodec codec)
270 {
271 _objectCodec = null;
272 _factoryFeatures = src._factoryFeatures;
273 _parserFeatures = src._parserFeatures;
274 _generatorFeatures = src._generatorFeatures;
275 _characterEscapes = src._characterEscapes;
276 _inputDecorator = src._inputDecorator;
277 _outputDecorator = src._outputDecorator;
278 _rootValueSeparator = src._rootValueSeparator;
279
280 /* 27-Apr-2013, tatu: How about symbol table; should we try to
281 * reuse shared symbol tables? Could be more efficient that way;
282 * although can slightly add to concurrency overhead.
283 */
284 }
285
286 /**
Tatu Saloranta378ecdc2012-08-04 16:27:27 -0700287 * Method for constructing a new {@link JsonFactory} that has
288 * the same settings as this instance, but is otherwise
289 * independent (i.e. nothing is actually shared, symbol tables
290 * are separate).
291 * Note that {@link ObjectCodec} reference is not copied but is
292 * set to null; caller typically needs to set it after calling
Tatu Saloranta7b796a82013-04-27 10:18:30 -0700293 * this method. Reason for this is that the codec is used for
294 * callbacks, and assumption is that there is strict 1-to-1
295 * mapping between codec, factory. Caller has to, then, explicitly
296 * set codec after making the copy.
Tatu Saloranta378ecdc2012-08-04 16:27:27 -0700297 *
298 * @since 2.1
299 */
300 public JsonFactory copy()
301 {
302 _checkInvalidCopy(JsonFactory.class);
Tatu Saloranta7b796a82013-04-27 10:18:30 -0700303 // as per above, do clear ObjectCodec
304 return new JsonFactory(this, null);
Tatu Saloranta378ecdc2012-08-04 16:27:27 -0700305 }
Tatu Saloranta7b796a82013-04-27 10:18:30 -0700306
Tatu Saloranta378ecdc2012-08-04 16:27:27 -0700307 /**
308 * @since 2.1
309 * @param exp
310 */
311 protected void _checkInvalidCopy(Class<?> exp)
312 {
313 if (getClass() != exp) {
314 throw new IllegalStateException("Failed copy(): "+getClass().getName()
315 +" (version: "+version()+") does not override copy(); it has to");
316 }
317 }
Tatu Saloranta95f76a42012-10-05 13:04:23 -0700318
319 /*
320 /**********************************************************
321 /* Serializable overrides
322 /**********************************************************
323 */
324
325 /**
326 * Method that we need to override to actually make restoration go
327 * through constructors etc.
328 * Also: must be overridden by sub-classes as well.
329 */
330 protected Object readResolve() {
Tatu Salorantaf7741c52013-04-27 11:06:30 -0700331 return new JsonFactory(this, _objectCodec);
Tatu Saloranta95f76a42012-10-05 13:04:23 -0700332 }
Tatu Salorantaa9e5c9f2013-08-28 19:39:59 -0700333
334 /*
335 /**********************************************************
336 /* Capability introspection
337 /**********************************************************
338 */
339
340 /**
341 * Introspection method that higher-level functionality may call
342 * to see whether underlying data format requires a stable ordering
343 * of object properties or not.
344 * This is usually used for determining
345 * whether to force a stable ordering (like alphabetic ordering by name)
346 * if no ordering if explicitly specified.
347 *<p>
348 * Default implementation returns <code>false</code> as JSON does NOT
349 * require stable ordering. Formats that require ordering include positional
350 * textual formats like <code>CSV</code>, and schema-based binary formats
351 * like <code>Avro</code>.
352 *
353 * @since 2.3
354 */
355 public boolean requiresPropertyOrdering() {
356 return false;
357 }
Tatu Salorantab8835442013-09-14 12:12:57 -0700358
359 /**
360 * Introspection method that higher-level functionality may call
361 * to see whether underlying data format can read and write binary
362 * data natively; that is, embeded it as-is without using encodings
363 * such as Base64.
364 *<p>
365 * Default implementation returns <code>false</code> as JSON does not
366 * support native access: all binary content must use Base64 encoding.
367 * Most binary formats (like Smile and Avro) support native binary content.
368 *
369 * @since 2.3
370 */
371 public boolean canHandleBinaryNatively(FormatSchema schema) {
372 return false;
373 }
374
Tatu Salorantaf15531c2011-12-22 23:00:40 -0800375 /*
376 /**********************************************************
377 /* Format detection functionality (since 1.8)
378 /**********************************************************
379 */
380
381 /**
Tatu Saloranta1bdf0262012-08-24 14:43:17 -0700382 * Method that can be used to quickly check whether given schema
383 * is something that parsers and/or generators constructed by this
384 * factory could use. Note that this means possible use, at the level
385 * of data format (i.e. schema is for same data format as parsers and
386 * generators this factory constructs); individual schema instances
387 * may have further usage restrictions.
388 *
389 * @since 2.1
390 */
391 public boolean canUseSchema(FormatSchema schema) {
392 String ourFormat = getFormatName();
393 return (ourFormat != null) && ourFormat.equals(schema.getSchemaType());
394 }
395
396 /**
Tatu Salorantaf15531c2011-12-22 23:00:40 -0800397 * Method that returns short textual id identifying format
398 * this factory supports.
399 *<p>
400 * Note: sub-classes should override this method; default
401 * implementation will return null for all sub-classes
402 */
403 public String getFormatName()
404 {
405 /* Somewhat nasty check: since we can't make this abstract
406 * (due to backwards compatibility concerns), need to prevent
407 * format name "leakage"
408 */
409 if (getClass() == JsonFactory.class) {
410 return FORMAT_NAME_JSON;
411 }
412 return null;
413 }
414
415 public MatchStrength hasFormat(InputAccessor acc) throws IOException
416 {
417 // since we can't keep this abstract, only implement for "vanilla" instance
418 if (getClass() == JsonFactory.class) {
419 return hasJSONFormat(acc);
420 }
421 return null;
422 }
423
Tatu Salorantaad2df5f2012-08-22 20:55:49 -0700424 /**
425 * Method that can be called to determine if a custom
426 * {@link ObjectCodec} is needed for binding data parsed
427 * using {@link JsonParser} constructed by this factory
428 * (which typically also implies the same for serialization
429 * with {@link JsonGenerator}).
430 *
431 * @return True if custom codec is needed with parsers and
432 * generators created by this factory; false if a general
433 * {@link ObjectCodec} is enough
434 *
435 * @since 2.1
436 */
437 public boolean requiresCustomCodec() {
438 return false;
439 }
440
441 /**
442 * Helper method that can be called to determine if content accessed
443 * using given accessor seems to be JSON content.
444 */
Tatu Salorantaf15531c2011-12-22 23:00:40 -0800445 protected MatchStrength hasJSONFormat(InputAccessor acc) throws IOException
446 {
447 return ByteSourceJsonBootstrapper.hasJSONFormat(acc);
Tatu Salorantaad2df5f2012-08-22 20:55:49 -0700448 }
449
Tatu Salorantaf15531c2011-12-22 23:00:40 -0800450 /*
451 /**********************************************************
452 /* Versioned
453 /**********************************************************
454 */
455
Tatu Saloranta68d79dd2013-01-10 21:13:46 -0800456 @Override
Tatu Salorantaf15531c2011-12-22 23:00:40 -0800457 public Version version() {
Tatu Saloranta68d79dd2013-01-10 21:13:46 -0800458 return PackageVersion.VERSION;
Tatu Salorantaf15531c2011-12-22 23:00:40 -0800459 }
460
461 /*
462 /**********************************************************
Tatu07351902012-01-19 13:12:13 -0800463 /* Configuration, factory features
Tatu Salorantaf15531c2011-12-22 23:00:40 -0800464 /**********************************************************
465 */
466
467 /**
468 * Method for enabling or disabling specified parser feature
469 * (check {@link JsonParser.Feature} for list of features)
470 */
Tatu07351902012-01-19 13:12:13 -0800471 public final JsonFactory configure(JsonFactory.Feature f, boolean state) {
472 return state ? enable(f) : disable(f);
473 }
474
475 /**
476 * Method for enabling specified parser feature
477 * (check {@link JsonFactory.Feature} for list of features)
478 */
479 public JsonFactory enable(JsonFactory.Feature f) {
480 _factoryFeatures |= f.getMask();
Tatu Salorantaf15531c2011-12-22 23:00:40 -0800481 return this;
482 }
483
484 /**
Tatu07351902012-01-19 13:12:13 -0800485 * Method for disabling specified parser features
486 * (check {@link JsonFactory.Feature} for list of features)
487 */
488 public JsonFactory disable(JsonFactory.Feature f) {
489 _factoryFeatures &= ~f.getMask();
490 return this;
491 }
492
493 /**
494 * Checked whether specified parser feature is enabled.
495 */
496 public final boolean isEnabled(JsonFactory.Feature f) {
497 return (_factoryFeatures & f.getMask()) != 0;
498 }
499
500 /*
501 /**********************************************************
502 /* Configuration, parser configuration
503 /**********************************************************
504 */
505
506 /**
507 * Method for enabling or disabling specified parser feature
508 * (check {@link JsonParser.Feature} for list of features)
509 */
510 public final JsonFactory configure(JsonParser.Feature f, boolean state) {
511 return state ? enable(f) : disable(f);
512 }
513
514 /**
Tatu Salorantaf15531c2011-12-22 23:00:40 -0800515 * Method for enabling specified parser feature
516 * (check {@link JsonParser.Feature} for list of features)
517 */
518 public JsonFactory enable(JsonParser.Feature f) {
519 _parserFeatures |= f.getMask();
520 return this;
521 }
522
523 /**
524 * Method for disabling specified parser features
525 * (check {@link JsonParser.Feature} for list of features)
526 */
527 public JsonFactory disable(JsonParser.Feature f) {
528 _parserFeatures &= ~f.getMask();
529 return this;
530 }
531
532 /**
533 * Checked whether specified parser feature is enabled.
534 */
535 public final boolean isEnabled(JsonParser.Feature f) {
536 return (_parserFeatures & f.getMask()) != 0;
537 }
538
539 /**
540 * Method for getting currently configured input decorator (if any;
541 * there is no default decorator).
542 */
543 public InputDecorator getInputDecorator() {
544 return _inputDecorator;
545 }
546
547 /**
548 * Method for overriding currently configured input decorator
549 */
550 public JsonFactory setInputDecorator(InputDecorator d) {
551 _inputDecorator = d;
552 return this;
553 }
554
555 /*
556 /**********************************************************
557 /* Configuration, generator settings
558 /**********************************************************
559 */
560
561 /**
562 * Method for enabling or disabling specified generator feature
563 * (check {@link JsonGenerator.Feature} for list of features)
564 */
565 public final JsonFactory configure(JsonGenerator.Feature f, boolean state) {
Tatu07351902012-01-19 13:12:13 -0800566 return state ? enable(f) : disable(f);
Tatu Salorantaf15531c2011-12-22 23:00:40 -0800567 }
568
569
570 /**
571 * Method for enabling specified generator features
572 * (check {@link JsonGenerator.Feature} for list of features)
573 */
574 public JsonFactory enable(JsonGenerator.Feature f) {
575 _generatorFeatures |= f.getMask();
576 return this;
577 }
578
579 /**
580 * Method for disabling specified generator feature
581 * (check {@link JsonGenerator.Feature} for list of features)
582 */
583 public JsonFactory disable(JsonGenerator.Feature f) {
584 _generatorFeatures &= ~f.getMask();
585 return this;
586 }
587
588 /**
589 * Check whether specified generator feature is enabled.
590 */
591 public final boolean isEnabled(JsonGenerator.Feature f) {
592 return (_generatorFeatures & f.getMask()) != 0;
593 }
594
595 /**
596 * Method for accessing custom escapes factory uses for {@link JsonGenerator}s
597 * it creates.
598 */
599 public CharacterEscapes getCharacterEscapes() {
600 return _characterEscapes;
601 }
602
603 /**
604 * Method for defining custom escapes factory uses for {@link JsonGenerator}s
605 * it creates.
606 */
607 public JsonFactory setCharacterEscapes(CharacterEscapes esc) {
608 _characterEscapes = esc;
609 return this;
610 }
611
612 /**
613 * Method for getting currently configured output decorator (if any;
614 * there is no default decorator).
615 */
616 public OutputDecorator getOutputDecorator() {
617 return _outputDecorator;
618 }
619
620 /**
621 * Method for overriding currently configured output decorator
622 */
623 public JsonFactory setOutputDecorator(OutputDecorator d) {
624 _outputDecorator = d;
625 return this;
626 }
Tatu Salorantae6dfc692012-09-28 15:34:05 -0700627
628 /**
629 * Method that allows overriding String used for separating root-level
630 * JSON values (default is single space character)
631 *
632 * @param sep Separator to use, if any; null means that no separator is
633 * automatically added
634 *
635 * @since 2.1
636 */
637 public JsonFactory setRootValueSeparator(String sep) {
638 _rootValueSeparator = (sep == null) ? null : new SerializedString(sep);
639 return this;
640 }
641
642 /**
643 * @since 2.1
644 */
645 public String getRootValueSeparator() {
646 return (_rootValueSeparator == null) ? null : _rootValueSeparator.getValue();
647 }
Tatu Salorantaf15531c2011-12-22 23:00:40 -0800648
649 /*
650 /**********************************************************
651 /* Configuration, other
652 /**********************************************************
653 */
654
655 /**
656 * Method for associating a {@link ObjectCodec} (typically
Tatu Salorantad77350e2011-12-22 23:13:13 -0800657 * a <code>com.fasterxml.jackson.databind.ObjectMapper</code>)
658 * with this factory (and more importantly, parsers and generators
Tatu Salorantaf15531c2011-12-22 23:00:40 -0800659 * it constructs). This is needed to use data-binding methods
660 * of {@link JsonParser} and {@link JsonGenerator} instances.
661 */
662 public JsonFactory setCodec(ObjectCodec oc) {
663 _objectCodec = oc;
664 return this;
665 }
666
667 public ObjectCodec getCodec() { return _objectCodec; }
668
669 /*
670 /**********************************************************
Tatu Salorantafeaabd12012-07-22 23:03:41 -0700671 /* Parser factories (new ones, as per [Issue-25])
Tatu Salorantaf15531c2011-12-22 23:00:40 -0800672 /**********************************************************
673 */
674
675 /**
676 * Method for constructing JSON parser instance to parse
677 * contents of specified file. Encoding is auto-detected
678 * from contents according to JSON specification recommended
679 * mechanism.
680 *<p>
681 * Underlying input stream (needed for reading contents)
682 * will be <b>owned</b> (and managed, i.e. closed as need be) by
683 * the parser, since caller has no access to it.
684 *
685 * @param f File that contains JSON content to parse
Tatu Salorantafeaabd12012-07-22 23:03:41 -0700686 *
687 * @since 2.1
688 */
689 public JsonParser createParser(File f)
690 throws IOException, JsonParseException
691 {
Tatu Salorantaf15531c2011-12-22 23:00:40 -0800692 // true, since we create InputStream from File
693 IOContext ctxt = _createContext(f, true);
694 InputStream in = new FileInputStream(f);
695 // [JACKSON-512]: allow wrapping with InputDecorator
696 if (_inputDecorator != null) {
697 in = _inputDecorator.decorate(ctxt, in);
698 }
Tatu Salorantaeeb2fbd2012-05-28 22:00:08 -0700699 return _createParser(in, ctxt);
Tatu Salorantaf15531c2011-12-22 23:00:40 -0800700 }
701
702 /**
703 * Method for constructing JSON parser instance to parse
704 * contents of resource reference by given URL.
705 * Encoding is auto-detected
706 * from contents according to JSON specification recommended
707 * mechanism.
708 *<p>
709 * Underlying input stream (needed for reading contents)
710 * will be <b>owned</b> (and managed, i.e. closed as need be) by
711 * the parser, since caller has no access to it.
712 *
713 * @param url URL pointing to resource that contains JSON content to parse
Tatu Saloranta68194922012-11-15 20:34:29 -0800714 *
715 * @since 2.1
Tatu Salorantaf15531c2011-12-22 23:00:40 -0800716 */
Tatu Saloranta68194922012-11-15 20:34:29 -0800717 public JsonParser createParser(URL url)
Tatu Salorantaf15531c2011-12-22 23:00:40 -0800718 throws IOException, JsonParseException
719 {
720 // true, since we create InputStream from URL
721 IOContext ctxt = _createContext(url, true);
722 InputStream in = _optimizedStreamFromURL(url);
723 // [JACKSON-512]: allow wrapping with InputDecorator
724 if (_inputDecorator != null) {
725 in = _inputDecorator.decorate(ctxt, in);
726 }
Tatu Salorantaeeb2fbd2012-05-28 22:00:08 -0700727 return _createParser(in, ctxt);
Tatu Salorantaf15531c2011-12-22 23:00:40 -0800728 }
729
730 /**
731 * Method for constructing JSON parser instance to parse
732 * the contents accessed via specified input stream.
733 *<p>
734 * The input stream will <b>not be owned</b> by
735 * the parser, it will still be managed (i.e. closed if
736 * end-of-stream is reacher, or parser close method called)
737 * if (and only if) {@link com.fasterxml.jackson.core.JsonParser.Feature#AUTO_CLOSE_SOURCE}
738 * is enabled.
739 *<p>
740 * Note: no encoding argument is taken since it can always be
Tatu Salorantafeaabd12012-07-22 23:03:41 -0700741 * auto-detected as suggested by JSON RFC.
Tatu Salorantaf15531c2011-12-22 23:00:40 -0800742 *
743 * @param in InputStream to use for reading JSON content to parse
Tatu Saloranta68194922012-11-15 20:34:29 -0800744 *
745 * @since 2.1
Tatu Salorantaf15531c2011-12-22 23:00:40 -0800746 */
Tatu Saloranta68194922012-11-15 20:34:29 -0800747 public JsonParser createParser(InputStream in)
Tatu Salorantaf15531c2011-12-22 23:00:40 -0800748 throws IOException, JsonParseException
749 {
750 IOContext ctxt = _createContext(in, false);
751 // [JACKSON-512]: allow wrapping with InputDecorator
752 if (_inputDecorator != null) {
753 in = _inputDecorator.decorate(ctxt, in);
754 }
Tatu Salorantaeeb2fbd2012-05-28 22:00:08 -0700755 return _createParser(in, ctxt);
Tatu Salorantaf15531c2011-12-22 23:00:40 -0800756 }
757
758 /**
759 * Method for constructing parser for parsing
760 * the contents accessed via specified Reader.
761 <p>
762 * The read stream will <b>not be owned</b> by
763 * the parser, it will still be managed (i.e. closed if
764 * end-of-stream is reacher, or parser close method called)
765 * if (and only if) {@link com.fasterxml.jackson.core.JsonParser.Feature#AUTO_CLOSE_SOURCE}
766 * is enabled.
Tatu Salorantaf15531c2011-12-22 23:00:40 -0800767 *
768 * @param r Reader to use for reading JSON content to parse
Tatu Saloranta68194922012-11-15 20:34:29 -0800769 *
770 * @since 2.1
Tatu Salorantaf15531c2011-12-22 23:00:40 -0800771 */
Tatu Saloranta68194922012-11-15 20:34:29 -0800772 public JsonParser createParser(Reader r)
Tatu Salorantaf15531c2011-12-22 23:00:40 -0800773 throws IOException, JsonParseException
774 {
775 // false -> we do NOT own Reader (did not create it)
776 IOContext ctxt = _createContext(r, false);
777 // [JACKSON-512]: allow wrapping with InputDecorator
778 if (_inputDecorator != null) {
779 r = _inputDecorator.decorate(ctxt, r);
780 }
Tatu Saloranta3e5ff6d2012-06-27 18:46:43 -0700781 return _createParser(r, ctxt);
Tatu Salorantaf15531c2011-12-22 23:00:40 -0800782 }
783
784 /**
785 * Method for constructing parser for parsing
786 * the contents of given byte array.
Tatu Saloranta68194922012-11-15 20:34:29 -0800787 *
788 * @since 2.1
Tatu Salorantaf15531c2011-12-22 23:00:40 -0800789 */
Tatu Saloranta68194922012-11-15 20:34:29 -0800790 public JsonParser createParser(byte[] data)
Tatu Salorantaf15531c2011-12-22 23:00:40 -0800791 throws IOException, JsonParseException
792 {
793 IOContext ctxt = _createContext(data, true);
794 // [JACKSON-512]: allow wrapping with InputDecorator
795 if (_inputDecorator != null) {
796 InputStream in = _inputDecorator.decorate(ctxt, data, 0, data.length);
797 if (in != null) {
Tatu Salorantaeeb2fbd2012-05-28 22:00:08 -0700798 return _createParser(in, ctxt);
Tatu Salorantaf15531c2011-12-22 23:00:40 -0800799 }
800 }
Tatu Salorantaeeb2fbd2012-05-28 22:00:08 -0700801 return _createParser(data, 0, data.length, ctxt);
Tatu Salorantaf15531c2011-12-22 23:00:40 -0800802 }
803
804 /**
805 * Method for constructing parser for parsing
806 * the contents of given byte array.
807 *
808 * @param data Buffer that contains data to parse
809 * @param offset Offset of the first data byte within buffer
810 * @param len Length of contents to parse within buffer
Tatu Saloranta68194922012-11-15 20:34:29 -0800811 *
812 * @since 2.1
Tatu Salorantaf15531c2011-12-22 23:00:40 -0800813 */
Tatu Saloranta68194922012-11-15 20:34:29 -0800814 public JsonParser createParser(byte[] data, int offset, int len)
Tatu Salorantaf15531c2011-12-22 23:00:40 -0800815 throws IOException, JsonParseException
816 {
817 IOContext ctxt = _createContext(data, true);
818 // [JACKSON-512]: allow wrapping with InputDecorator
819 if (_inputDecorator != null) {
820 InputStream in = _inputDecorator.decorate(ctxt, data, offset, len);
821 if (in != null) {
Tatu Salorantaeeb2fbd2012-05-28 22:00:08 -0700822 return _createParser(in, ctxt);
Tatu Salorantaf15531c2011-12-22 23:00:40 -0800823 }
824 }
Tatu Saloranta68194922012-11-15 20:34:29 -0800825 return _createParser(data, offset, len, ctxt);
Tatu Salorantaf15531c2011-12-22 23:00:40 -0800826 }
827
828 /**
829 * Method for constructing parser for parsing
830 * contents of given String.
Tatu Saloranta68194922012-11-15 20:34:29 -0800831 *
832 * @since 2.1
Tatu Salorantaf15531c2011-12-22 23:00:40 -0800833 */
Tatu Saloranta68194922012-11-15 20:34:29 -0800834 public JsonParser createParser(String content)
Tatu Salorantaf15531c2011-12-22 23:00:40 -0800835 throws IOException, JsonParseException
836 {
Tatu Saloranta3e5ff6d2012-06-27 18:46:43 -0700837 Reader r = new StringReader(content);
Tatu Salorantaf15531c2011-12-22 23:00:40 -0800838 // true -> we own the Reader (and must close); not a big deal
839 IOContext ctxt = _createContext(r, true);
840 // [JACKSON-512]: allow wrapping with InputDecorator
841 if (_inputDecorator != null) {
842 r = _inputDecorator.decorate(ctxt, r);
843 }
Tatu Saloranta3e5ff6d2012-06-27 18:46:43 -0700844 return _createParser(r, ctxt);
Tatu Salorantaf15531c2011-12-22 23:00:40 -0800845 }
846
847 /*
848 /**********************************************************
Tatu Saloranta68194922012-11-15 20:34:29 -0800849 /* Parser factories (old ones, as per [Issue-25])
850 /**********************************************************
851 */
852
853 /**
854 * Method for constructing JSON parser instance to parse
855 * contents of specified file. Encoding is auto-detected
856 * from contents according to JSON specification recommended
857 * mechanism.
858 *<p>
859 * Underlying input stream (needed for reading contents)
860 * will be <b>owned</b> (and managed, i.e. closed as need be) by
861 * the parser, since caller has no access to it.
862 *<p>
863 * NOTE: as of 2.1, should not be used (will be deprecated in 2.2);
864 * instead, should call <code>createParser</code>.
865 *
866 * @param f File that contains JSON content to parse
867 *
868 * @deprecated Since 2.2, use {@link #createParser(File)} instead.
869 */
870 @Deprecated
871 public JsonParser createJsonParser(File f)
872 throws IOException, JsonParseException
873 {
874 return createParser(f);
875 }
876
877 /**
878 * Method for constructing JSON parser instance to parse
879 * contents of resource reference by given URL.
880 * Encoding is auto-detected
881 * from contents according to JSON specification recommended
882 * mechanism.
883 *<p>
884 * Underlying input stream (needed for reading contents)
885 * will be <b>owned</b> (and managed, i.e. closed as need be) by
886 * the parser, since caller has no access to it.
887 *<p>
888 * NOTE: as of 2.1, should not be used (will be deprecated in 2.2);
889 * instead, should call <code>createParser</code>.
890 *
891 * @param url URL pointing to resource that contains JSON content to parse
892 *
893 * @deprecated Since 2.2, use {@link #createParser(URL)} instead.
894 */
895 @Deprecated
896 public JsonParser createJsonParser(URL url)
897 throws IOException, JsonParseException
898 {
899 return createParser(url);
900 }
901
902 /**
903 * Method for constructing JSON parser instance to parse
904 * the contents accessed via specified input stream.
905 *<p>
906 * The input stream will <b>not be owned</b> by
907 * the parser, it will still be managed (i.e. closed if
908 * end-of-stream is reacher, or parser close method called)
909 * if (and only if) {@link com.fasterxml.jackson.core.JsonParser.Feature#AUTO_CLOSE_SOURCE}
910 * is enabled.
911 *<p>
912 * Note: no encoding argument is taken since it can always be
913 * auto-detected as suggested by JSON RFC.
914 *<p>
915 * NOTE: as of 2.1, should not be used (will be deprecated in 2.2);
916 * instead, should call <code>createParser</code>.
917 *
918 * @param in InputStream to use for reading JSON content to parse
919 *
920 * @deprecated Since 2.2, use {@link #createParser(InputStream)} instead.
921 */
922 @Deprecated
923 public JsonParser createJsonParser(InputStream in)
924 throws IOException, JsonParseException
925 {
926 return createParser(in);
927 }
928
929 /**
930 * Method for constructing parser for parsing
931 * the contents accessed via specified Reader.
932 <p>
933 * The read stream will <b>not be owned</b> by
934 * the parser, it will still be managed (i.e. closed if
935 * end-of-stream is reacher, or parser close method called)
936 * if (and only if) {@link com.fasterxml.jackson.core.JsonParser.Feature#AUTO_CLOSE_SOURCE}
937 * is enabled.
938 *<p>
939 * NOTE: as of 2.1, should not be used (will be deprecated in 2.2);
940 * instead, should call <code>createParser</code>.
941 *
942 * @param r Reader to use for reading JSON content to parse
943 *
944 * @deprecated Since 2.2, use {@link #createParser(Reader)} instead.
945 */
946 @Deprecated
947 public JsonParser createJsonParser(Reader r)
948 throws IOException, JsonParseException
949 {
950 return createParser(r);
951 }
952
953 /**
954 * Method for constructing parser for parsing
955 * the contents of given byte array.
956 *<p>
957 * NOTE: as of 2.1, should not be used (will be deprecated in 2.2);
958 * instead, should call <code>createParser</code>.
959 *
960 * @deprecated Since 2.2, use {@link #createParser(byte[])} instead.
961 */
962 @Deprecated
963 public JsonParser createJsonParser(byte[] data)
964 throws IOException, JsonParseException
965 {
966 return createParser(data);
967 }
968
969 /**
970 * Method for constructing parser for parsing
971 * the contents of given byte array.
972 *<p>
973 * NOTE: as of 2.1, should not be used (will be deprecated in 2.2);
974 * instead, should call <code>createParser</code>.
975 *
976 * @param data Buffer that contains data to parse
977 * @param offset Offset of the first data byte within buffer
978 * @param len Length of contents to parse within buffer
979 *
980 * @deprecated Since 2.2, use {@link #createParser(byte[],int,int)} instead.
981 */
982 @Deprecated
983 public JsonParser createJsonParser(byte[] data, int offset, int len)
984 throws IOException, JsonParseException
985 {
986 return createParser(data, offset, len);
987 }
988
989 /**
990 * Method for constructing parser for parsing
991 * contents of given String.
992 *
993 * @deprecated Since 2.2, use {@link #createParser(String)} instead.
994 */
995 @Deprecated
996 public JsonParser createJsonParser(String content)
997 throws IOException, JsonParseException
998 {
999 return createParser(content);
1000 }
1001
1002 /*
1003 /**********************************************************
Tatu Salorantafeaabd12012-07-22 23:03:41 -07001004 /* Generator factories, new (as per [Issue-25]
Tatu Salorantaf15531c2011-12-22 23:00:40 -08001005 /**********************************************************
1006 */
1007
1008 /**
1009 * Method for constructing JSON generator for writing JSON content
1010 * using specified output stream.
1011 * Encoding to use must be specified, and needs to be one of available
1012 * types (as per JSON specification).
1013 *<p>
1014 * Underlying stream <b>is NOT owned</b> by the generator constructed,
1015 * so that generator will NOT close the output stream when
1016 * {@link JsonGenerator#close} is called (unless auto-closing
1017 * feature,
1018 * {@link com.fasterxml.jackson.core.JsonGenerator.Feature#AUTO_CLOSE_TARGET}
1019 * is enabled).
1020 * Using application needs to close it explicitly if this is the case.
1021 *<p>
1022 * Note: there are formats that use fixed encoding (like most binary data formats)
1023 * and that ignore passed in encoding.
Tatu Salorantafeaabd12012-07-22 23:03:41 -07001024 *
1025 * @param out OutputStream to use for writing JSON content
1026 * @param enc Character encoding to use
Tatu Saloranta4ab04ce2012-11-15 20:42:16 -08001027 *
1028 * @since 2.1
Tatu Salorantafeaabd12012-07-22 23:03:41 -07001029 */
1030 public JsonGenerator createGenerator(OutputStream out, JsonEncoding enc)
1031 throws IOException
1032 {
Tatu Saloranta4ab04ce2012-11-15 20:42:16 -08001033 // false -> we won't manage the stream unless explicitly directed to
1034 IOContext ctxt = _createContext(out, false);
1035 ctxt.setEncoding(enc);
1036 if (enc == JsonEncoding.UTF8) {
1037 // [JACKSON-512]: allow wrapping with _outputDecorator
1038 if (_outputDecorator != null) {
1039 out = _outputDecorator.decorate(ctxt, out);
1040 }
1041 return _createUTF8Generator(out, ctxt);
1042 }
1043 Writer w = _createWriter(out, enc, ctxt);
1044 // [JACKSON-512]: allow wrapping with _outputDecorator
1045 if (_outputDecorator != null) {
1046 w = _outputDecorator.decorate(ctxt, w);
1047 }
1048 return _createGenerator(w, ctxt);
Tatu Salorantafeaabd12012-07-22 23:03:41 -07001049 }
1050
1051 /**
Tatu Saloranta4ab04ce2012-11-15 20:42:16 -08001052 * Convenience method for constructing generator that uses default
1053 * encoding of the format (UTF-8 for JSON and most other data formats).
1054 *<p>
1055 * Note: there are formats that use fixed encoding (like most binary data formats).
1056 *
1057 * @since 2.1
1058 */
1059 public JsonGenerator createGenerator(OutputStream out) throws IOException {
1060 return createGenerator(out, JsonEncoding.UTF8);
1061 }
1062
1063 /**
Tatu Salorantafeaabd12012-07-22 23:03:41 -07001064 * Method for constructing JSON generator for writing JSON content
1065 * using specified Writer.
1066 *<p>
1067 * Underlying stream <b>is NOT owned</b> by the generator constructed,
1068 * so that generator will NOT close the Reader when
1069 * {@link JsonGenerator#close} is called (unless auto-closing
1070 * feature,
1071 * {@link com.fasterxml.jackson.core.JsonGenerator.Feature#AUTO_CLOSE_TARGET} is enabled).
1072 * Using application needs to close it explicitly.
Tatu Salorantafeaabd12012-07-22 23:03:41 -07001073 *
Tatu Saloranta4ab04ce2012-11-15 20:42:16 -08001074 * @since 2.1
Tatu Salorantafeaabd12012-07-22 23:03:41 -07001075 *
1076 * @param out Writer to use for writing JSON content
1077 */
1078 public JsonGenerator createGenerator(Writer out)
1079 throws IOException
1080 {
Tatu Saloranta4ab04ce2012-11-15 20:42:16 -08001081 IOContext ctxt = _createContext(out, false);
1082 // [JACKSON-512]: allow wrapping with _outputDecorator
1083 if (_outputDecorator != null) {
1084 out = _outputDecorator.decorate(ctxt, out);
1085 }
1086 return _createGenerator(out, ctxt);
Tatu Salorantafeaabd12012-07-22 23:03:41 -07001087 }
1088
1089 /**
1090 * Method for constructing JSON generator for writing JSON content
1091 * to specified file, overwriting contents it might have (or creating
1092 * it if such file does not yet exist).
1093 * Encoding to use must be specified, and needs to be one of available
1094 * types (as per JSON specification).
1095 *<p>
1096 * Underlying stream <b>is owned</b> by the generator constructed,
1097 * i.e. generator will handle closing of file when
1098 * {@link JsonGenerator#close} is called.
Tatu Salorantafeaabd12012-07-22 23:03:41 -07001099 *
1100 * @param f File to write contents to
1101 * @param enc Character encoding to use
Tatu Saloranta4ab04ce2012-11-15 20:42:16 -08001102 *
1103 * @since 2.1
Tatu Salorantafeaabd12012-07-22 23:03:41 -07001104 */
1105 public JsonGenerator createGenerator(File f, JsonEncoding enc)
1106 throws IOException
1107 {
Tatu Saloranta4ab04ce2012-11-15 20:42:16 -08001108 OutputStream out = new FileOutputStream(f);
1109 // true -> yes, we have to manage the stream since we created it
1110 IOContext ctxt = _createContext(out, true);
1111 ctxt.setEncoding(enc);
1112 if (enc == JsonEncoding.UTF8) {
1113 // [JACKSON-512]: allow wrapping with _outputDecorator
1114 if (_outputDecorator != null) {
1115 out = _outputDecorator.decorate(ctxt, out);
1116 }
1117 return _createUTF8Generator(out, ctxt);
1118 }
1119 Writer w = _createWriter(out, enc, ctxt);
1120 // [JACKSON-512]: allow wrapping with _outputDecorator
1121 if (_outputDecorator != null) {
1122 w = _outputDecorator.decorate(ctxt, w);
1123 }
1124 return _createGenerator(w, ctxt);
Tatu Salorantafeaabd12012-07-22 23:03:41 -07001125 }
1126
1127 /*
1128 /**********************************************************
1129 /* Generator factories, old (as per [Issue-25]
1130 /**********************************************************
1131 */
1132
1133 /**
1134 * Method for constructing JSON generator for writing JSON content
1135 * using specified output stream.
1136 * Encoding to use must be specified, and needs to be one of available
1137 * types (as per JSON specification).
1138 *<p>
1139 * Underlying stream <b>is NOT owned</b> by the generator constructed,
1140 * so that generator will NOT close the output stream when
1141 * {@link JsonGenerator#close} is called (unless auto-closing
1142 * feature,
1143 * {@link com.fasterxml.jackson.core.JsonGenerator.Feature#AUTO_CLOSE_TARGET}
1144 * is enabled).
1145 * Using application needs to close it explicitly if this is the case.
1146 *<p>
1147 * Note: there are formats that use fixed encoding (like most binary data formats)
1148 * and that ignore passed in encoding.
Tatu Salorantaf15531c2011-12-22 23:00:40 -08001149 *
1150 * @param out OutputStream to use for writing JSON content
1151 * @param enc Character encoding to use
Tatu Saloranta4ab04ce2012-11-15 20:42:16 -08001152 *
1153 * @deprecated Since 2.2, use {@link #createGenerator(OutputStream, JsonEncoding)} instead.
Tatu Salorantaf15531c2011-12-22 23:00:40 -08001154 */
Tatu Saloranta4ab04ce2012-11-15 20:42:16 -08001155 @Deprecated
Tatu Salorantaf15531c2011-12-22 23:00:40 -08001156 public JsonGenerator createJsonGenerator(OutputStream out, JsonEncoding enc)
1157 throws IOException
1158 {
Tatu Saloranta4ab04ce2012-11-15 20:42:16 -08001159 return createGenerator(out, enc);
Tatu Salorantaf15531c2011-12-22 23:00:40 -08001160 }
1161
1162 /**
1163 * Method for constructing JSON generator for writing JSON content
1164 * using specified Writer.
1165 *<p>
1166 * Underlying stream <b>is NOT owned</b> by the generator constructed,
1167 * so that generator will NOT close the Reader when
1168 * {@link JsonGenerator#close} is called (unless auto-closing
1169 * feature,
1170 * {@link com.fasterxml.jackson.core.JsonGenerator.Feature#AUTO_CLOSE_TARGET} is enabled).
1171 * Using application needs to close it explicitly.
1172 *
1173 * @param out Writer to use for writing JSON content
Tatu Saloranta4ab04ce2012-11-15 20:42:16 -08001174 *
1175 * @deprecated Since 2.2, use {@link #createGenerator(Writer)} instead.
Tatu Salorantaf15531c2011-12-22 23:00:40 -08001176 */
Tatu Saloranta4ab04ce2012-11-15 20:42:16 -08001177 @Deprecated
Tatu Salorantaf15531c2011-12-22 23:00:40 -08001178 public JsonGenerator createJsonGenerator(Writer out)
1179 throws IOException
1180 {
Tatu Saloranta4ab04ce2012-11-15 20:42:16 -08001181 return createGenerator(out);
Tatu Salorantaf15531c2011-12-22 23:00:40 -08001182 }
1183
1184 /**
1185 * Convenience method for constructing generator that uses default
1186 * encoding of the format (UTF-8 for JSON and most other data formats).
1187 *<p>
1188 * Note: there are formats that use fixed encoding (like most binary data formats).
Tatu Saloranta4ab04ce2012-11-15 20:42:16 -08001189 *
1190 * @deprecated Since 2.2, use {@link #createGenerator(OutputStream)} instead.
Tatu Salorantaf15531c2011-12-22 23:00:40 -08001191 */
Tatu Saloranta4ab04ce2012-11-15 20:42:16 -08001192 @Deprecated
Tatu Salorantaf15531c2011-12-22 23:00:40 -08001193 public JsonGenerator createJsonGenerator(OutputStream out) throws IOException {
Tatu Saloranta4ab04ce2012-11-15 20:42:16 -08001194 return createGenerator(out, JsonEncoding.UTF8);
Tatu Salorantaf15531c2011-12-22 23:00:40 -08001195 }
1196
1197 /**
1198 * Method for constructing JSON generator for writing JSON content
1199 * to specified file, overwriting contents it might have (or creating
1200 * it if such file does not yet exist).
1201 * Encoding to use must be specified, and needs to be one of available
1202 * types (as per JSON specification).
1203 *<p>
1204 * Underlying stream <b>is owned</b> by the generator constructed,
1205 * i.e. generator will handle closing of file when
1206 * {@link JsonGenerator#close} is called.
1207 *
1208 * @param f File to write contents to
1209 * @param enc Character encoding to use
Tatu Saloranta4ab04ce2012-11-15 20:42:16 -08001210 *
1211 *
1212 * @deprecated Since 2.2, use {@link #createGenerator(File,JsonEncoding)} instead.
Tatu Salorantaf15531c2011-12-22 23:00:40 -08001213 */
Tatu Saloranta4ab04ce2012-11-15 20:42:16 -08001214 @Deprecated
Tatu Salorantaf15531c2011-12-22 23:00:40 -08001215 public JsonGenerator createJsonGenerator(File f, JsonEncoding enc)
1216 throws IOException
1217 {
Tatu Saloranta4ab04ce2012-11-15 20:42:16 -08001218 return createGenerator(f, enc);
Tatu Salorantaf15531c2011-12-22 23:00:40 -08001219 }
1220
1221 /*
1222 /**********************************************************
1223 /* Factory methods used by factory for creating parser instances,
1224 /* overridable by sub-classes
1225 /**********************************************************
1226 */
1227
1228 /**
1229 * Overridable factory method that actually instantiates desired parser
1230 * given {@link InputStream} and context object.
1231 *<p>
1232 * This method is specifically designed to remain
1233 * compatible between minor versions so that sub-classes can count
1234 * on it being called as expected. That is, it is part of official
1235 * interface from sub-class perspective, although not a public
1236 * method available to users of factory implementations.
Tatu Salorantaeeb2fbd2012-05-28 22:00:08 -07001237 *
1238 * @since 2.1
Tatu Salorantaf15531c2011-12-22 23:00:40 -08001239 */
Tatu Salorantaeeb2fbd2012-05-28 22:00:08 -07001240 protected JsonParser _createParser(InputStream in, IOContext ctxt)
Tatu Salorantaf15531c2011-12-22 23:00:40 -08001241 throws IOException, JsonParseException
1242 {
Tatu Saloranta68194922012-11-15 20:34:29 -08001243 // As per [JACKSON-259], may want to fully disable canonicalization:
1244 return new ByteSourceJsonBootstrapper(ctxt, in).constructParser(_parserFeatures,
1245 _objectCodec, _rootByteSymbols, _rootCharSymbols,
1246 isEnabled(JsonFactory.Feature.CANONICALIZE_FIELD_NAMES),
1247 isEnabled(JsonFactory.Feature.INTERN_FIELD_NAMES));
Tatu Salorantaeeb2fbd2012-05-28 22:00:08 -07001248 }
1249
1250 /**
1251 * @deprecated since 2.1 -- use {@link #_createParser(InputStream, IOContext)} instead
1252 */
1253 @Deprecated
1254 protected JsonParser _createJsonParser(InputStream in, IOContext ctxt) throws IOException, JsonParseException {
Tatu Saloranta68194922012-11-15 20:34:29 -08001255 return _createParser(in, ctxt);
Tatu Salorantaf15531c2011-12-22 23:00:40 -08001256 }
Tatu Salorantaeeb2fbd2012-05-28 22:00:08 -07001257
Tatu Salorantaf15531c2011-12-22 23:00:40 -08001258 /**
1259 * Overridable factory method that actually instantiates parser
1260 * using given {@link Reader} object for reading content.
1261 *<p>
1262 * This method is specifically designed to remain
1263 * compatible between minor versions so that sub-classes can count
1264 * on it being called as expected. That is, it is part of official
1265 * interface from sub-class perspective, although not a public
1266 * method available to users of factory implementations.
Tatu Salorantaeeb2fbd2012-05-28 22:00:08 -07001267 *
1268 * @since 2.1
Tatu Salorantaf15531c2011-12-22 23:00:40 -08001269 */
Tatu Salorantaeeb2fbd2012-05-28 22:00:08 -07001270 protected JsonParser _createParser(Reader r, IOContext ctxt)
1271 throws IOException, JsonParseException
Tatu Salorantaf15531c2011-12-22 23:00:40 -08001272 {
Tatu Saloranta68194922012-11-15 20:34:29 -08001273 return new ReaderBasedJsonParser(ctxt, _parserFeatures, r, _objectCodec,
1274 _rootCharSymbols.makeChild(isEnabled(JsonFactory.Feature.CANONICALIZE_FIELD_NAMES),
1275 isEnabled(JsonFactory.Feature.INTERN_FIELD_NAMES)));
Tatu Salorantaeeb2fbd2012-05-28 22:00:08 -07001276 }
1277
1278 /**
1279 * @deprecated since 2.1 -- use {@link #_createParser(Reader, IOContext)} instead
1280 */
1281 @Deprecated
1282 protected JsonParser _createJsonParser(Reader r, IOContext ctxt) throws IOException, JsonParseException {
Tatu Saloranta68194922012-11-15 20:34:29 -08001283 return _createParser(r, ctxt);
Tatu Salorantaf15531c2011-12-22 23:00:40 -08001284 }
1285
1286 /**
1287 * Overridable factory method that actually instantiates parser
1288 * using given {@link Reader} object for reading content
1289 * passed as raw byte array.
1290 *<p>
1291 * This method is specifically designed to remain
1292 * compatible between minor versions so that sub-classes can count
1293 * on it being called as expected. That is, it is part of official
1294 * interface from sub-class perspective, although not a public
1295 * method available to users of factory implementations.
1296 */
Tatu Salorantaeeb2fbd2012-05-28 22:00:08 -07001297 protected JsonParser _createParser(byte[] data, int offset, int len, IOContext ctxt)
Tatu Salorantaf15531c2011-12-22 23:00:40 -08001298 throws IOException, JsonParseException
1299 {
Tatu Saloranta68194922012-11-15 20:34:29 -08001300 return new ByteSourceJsonBootstrapper(ctxt, data, offset, len).constructParser(_parserFeatures,
1301 _objectCodec, _rootByteSymbols, _rootCharSymbols,
1302 isEnabled(JsonFactory.Feature.CANONICALIZE_FIELD_NAMES),
1303 isEnabled(JsonFactory.Feature.INTERN_FIELD_NAMES));
Tatu Salorantaeeb2fbd2012-05-28 22:00:08 -07001304 }
1305
1306 /**
1307 * @deprecated since 2.1 -- use {@link #_createParser(byte[], int, int, IOContext)} instead
1308 */
1309 @Deprecated
1310 protected JsonParser _createJsonParser(byte[] data, int offset, int len, IOContext ctxt) throws IOException, JsonParseException {
Tatu Saloranta68194922012-11-15 20:34:29 -08001311 return _createParser(data, offset, len, ctxt);
Tatu Salorantaf15531c2011-12-22 23:00:40 -08001312 }
Tatu Salorantaeeb2fbd2012-05-28 22:00:08 -07001313
Tatu Salorantaf15531c2011-12-22 23:00:40 -08001314 /*
1315 /**********************************************************
1316 /* Factory methods used by factory for creating generator instances,
1317 /* overridable by sub-classes
1318 /**********************************************************
1319 */
1320
1321 /**
1322 * Overridable factory method that actually instantiates generator for
1323 * given {@link Writer} and context object.
1324 *<p>
1325 * This method is specifically designed to remain
1326 * compatible between minor versions so that sub-classes can count
1327 * on it being called as expected. That is, it is part of official
1328 * interface from sub-class perspective, although not a public
1329 * method available to users of factory implementations.
1330 */
Tatu Salorantaeeb2fbd2012-05-28 22:00:08 -07001331 protected JsonGenerator _createGenerator(Writer out, IOContext ctxt)
1332 throws IOException
1333 {
Tatu Salorantae6dfc692012-09-28 15:34:05 -07001334 WriterBasedJsonGenerator gen = new WriterBasedJsonGenerator(ctxt,
1335 _generatorFeatures, _objectCodec, out);
Tatu Salorantaf15531c2011-12-22 23:00:40 -08001336 if (_characterEscapes != null) {
1337 gen.setCharacterEscapes(_characterEscapes);
1338 }
Tatu Salorantae6dfc692012-09-28 15:34:05 -07001339 SerializableString rootSep = _rootValueSeparator;
1340 if (rootSep != DEFAULT_ROOT_VALUE_SEPARATOR) {
1341 gen.setRootValueSeparator(rootSep);
1342 }
Tatu Salorantaf15531c2011-12-22 23:00:40 -08001343 return gen;
1344 }
1345
1346 /**
Tatu Saloranta68194922012-11-15 20:34:29 -08001347 * @deprecated since 2.1 -- use {@link #_createGenerator(Writer, IOContext)} instead
1348 */
1349 @Deprecated
1350 protected JsonGenerator _createJsonGenerator(Writer out, IOContext ctxt)
1351 throws IOException
1352 {
1353 /* NOTE: MUST call the deprecated method until it is deleted, just so
1354 * that override still works as expected, for now.
1355 */
1356 return _createGenerator(out, ctxt);
1357 }
1358
1359 /**
Tatu Salorantaf15531c2011-12-22 23:00:40 -08001360 * Overridable factory method that actually instantiates generator for
1361 * given {@link OutputStream} and context object, using UTF-8 encoding.
1362 *<p>
1363 * This method is specifically designed to remain
1364 * compatible between minor versions so that sub-classes can count
1365 * on it being called as expected. That is, it is part of official
1366 * interface from sub-class perspective, although not a public
1367 * method available to users of factory implementations.
1368 */
Tatu Salorantaeeb2fbd2012-05-28 22:00:08 -07001369 protected JsonGenerator _createUTF8Generator(OutputStream out, IOContext ctxt) throws IOException {
Tatu Salorantae6dfc692012-09-28 15:34:05 -07001370 UTF8JsonGenerator gen = new UTF8JsonGenerator(ctxt,
1371 _generatorFeatures, _objectCodec, out);
Tatu Salorantaf15531c2011-12-22 23:00:40 -08001372 if (_characterEscapes != null) {
1373 gen.setCharacterEscapes(_characterEscapes);
1374 }
Tatu Salorantae6dfc692012-09-28 15:34:05 -07001375 SerializableString rootSep = _rootValueSeparator;
1376 if (rootSep != DEFAULT_ROOT_VALUE_SEPARATOR) {
1377 gen.setRootValueSeparator(rootSep);
1378 }
Tatu Salorantaf15531c2011-12-22 23:00:40 -08001379 return gen;
1380 }
1381
Tatu Saloranta68194922012-11-15 20:34:29 -08001382 /**
1383 * @deprecated since 2.1
1384 */
1385 @Deprecated
1386 protected JsonGenerator _createUTF8JsonGenerator(OutputStream out, IOContext ctxt)
1387 throws IOException
1388 {
1389 return _createUTF8Generator(out, ctxt);
1390 }
1391
Tatu Salorantaf15531c2011-12-22 23:00:40 -08001392 protected Writer _createWriter(OutputStream out, JsonEncoding enc, IOContext ctxt) throws IOException
1393 {
1394 // note: this should not get called any more (caller checks, dispatches)
1395 if (enc == JsonEncoding.UTF8) { // We have optimized writer for UTF-8
1396 return new UTF8Writer(ctxt, out);
1397 }
1398 // not optimal, but should do unless we really care about UTF-16/32 encoding speed
1399 return new OutputStreamWriter(out, enc.getJavaName());
1400 }
1401
1402 /*
1403 /**********************************************************
1404 /* Internal factory methods, other
1405 /**********************************************************
1406 */
1407
1408 /**
1409 * Overridable factory method that actually instantiates desired
1410 * context object.
1411 */
1412 protected IOContext _createContext(Object srcRef, boolean resourceManaged)
1413 {
1414 return new IOContext(_getBufferRecycler(), srcRef, resourceManaged);
1415 }
1416
1417 /**
1418 * Method used by factory to create buffer recycler instances
1419 * for parsers and generators.
1420 *<p>
1421 * Note: only public to give access for <code>ObjectMapper</code>
1422 */
1423 public BufferRecycler _getBufferRecycler()
1424 {
1425 SoftReference<BufferRecycler> ref = _recyclerRef.get();
1426 BufferRecycler br = (ref == null) ? null : ref.get();
1427
1428 if (br == null) {
1429 br = new BufferRecycler();
1430 _recyclerRef.set(new SoftReference<BufferRecycler>(br));
1431 }
1432 return br;
1433 }
1434
1435 /**
1436 * Helper methods used for constructing an optimal stream for
1437 * parsers to use, when input is to be read from an URL.
1438 * This helps when reading file content via URL.
1439 */
1440 protected InputStream _optimizedStreamFromURL(URL url)
1441 throws IOException
1442 {
1443 if ("file".equals(url.getProtocol())) {
1444 /* Can not do this if the path refers
1445 * to a network drive on windows. This fixes the problem;
1446 * might not be needed on all platforms (NFS?), but should not
1447 * matter a lot: performance penalty of extra wrapping is more
1448 * relevant when accessing local file system.
1449 */
1450 String host = url.getHost();
1451 if (host == null || host.length() == 0) {
Tatu Saloranta61d5bdd2013-01-11 19:02:01 -08001452 // [Issue#48]: Let's try to avoid probs with URL encoded stuff
1453 String path = url.getPath();
1454 if (path.indexOf('%') < 0) {
1455 return new FileInputStream(url.getPath());
1456
1457 }
1458 // otherwise, let's fall through and let URL decoder do its magic
Tatu Salorantaf15531c2011-12-22 23:00:40 -08001459 }
1460 }
1461 return url.openStream();
1462 }
1463}