blob: d5805d449a844256e4c440ae435dd8669aca883d [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
4 *
5 * Licensed under the License specified in file LICENSE, included with
6 * the source code and binary code bundles.
7 * You may not use this file except in compliance with the License.
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15package com.fasterxml.jackson.core;
16
17import java.io.*;
18import java.lang.ref.SoftReference;
19import java.net.URL;
20
21import com.fasterxml.jackson.core.format.InputAccessor;
22import com.fasterxml.jackson.core.format.MatchStrength;
23import com.fasterxml.jackson.core.io.*;
Tatu07351902012-01-19 13:12:13 -080024import com.fasterxml.jackson.core.json.*;
Tatu Salorantaf15531c2011-12-22 23:00:40 -080025import com.fasterxml.jackson.core.sym.BytesToNameCanonicalizer;
26import com.fasterxml.jackson.core.sym.CharsToNameCanonicalizer;
27import com.fasterxml.jackson.core.util.BufferRecycler;
Tatu Salorantae6dfc692012-09-28 15:34:05 -070028import com.fasterxml.jackson.core.util.DefaultPrettyPrinter;
Tatu Salorantaf15531c2011-12-22 23:00:40 -080029
30/**
31 * The main factory class of Jackson package, used to configure and
32 * construct reader (aka parser, {@link JsonParser})
33 * and writer (aka generator, {@link JsonGenerator})
34 * instances.
35 *<p>
36 * Factory instances are thread-safe and reusable after configuration
37 * (if any). Typically applications and services use only a single
38 * globally shared factory instance, unless they need differently
39 * configured factories. Factory reuse is important if efficiency matters;
40 * most recycling of expensive construct is done on per-factory basis.
41 *<p>
42 * Creation of a factory instance is a light-weight operation,
43 * and since there is no need for pluggable alternative implementations
44 * (as there is no "standard" JSON processor API to implement),
45 * the default constructor is used for constructing factory
46 * instances.
47 *
48 * @author Tatu Saloranta
49 */
Tatu Saloranta95f76a42012-10-05 13:04:23 -070050public class JsonFactory
51 implements Versioned,
52 java.io.Serializable // since 2.1 (for Android, mostly)
Tatu Salorantaf15531c2011-12-22 23:00:40 -080053{
54 /**
Tatu Saloranta95f76a42012-10-05 13:04:23 -070055 * Computed for Jackson 2.1.0 release
56 */
57 private static final long serialVersionUID = -5207101305402257257L;
58
59 /**
Tatu Salorantaf15531c2011-12-22 23:00:40 -080060 * Name used to identify JSON format
61 * (and returned by {@link #getFormatName()}
62 */
63 public final static String FORMAT_NAME_JSON = "JSON";
64
65 /**
Tatu07351902012-01-19 13:12:13 -080066 * Bitfield (set of flags) of all factory features that are enabled by default.
67 */
68 protected final static int DEFAULT_FACTORY_FEATURE_FLAGS = JsonFactory.Feature.collectDefaults();
69
70 /**
Tatu Salorantaf15531c2011-12-22 23:00:40 -080071 * Bitfield (set of flags) of all parser features that are enabled
72 * by default.
73 */
Tatu07351902012-01-19 13:12:13 -080074 protected final static int DEFAULT_PARSER_FEATURE_FLAGS = JsonParser.Feature.collectDefaults();
75
Tatu Salorantaf15531c2011-12-22 23:00:40 -080076 /**
77 * Bitfield (set of flags) of all generator features that are enabled
78 * by default.
79 */
Tatu07351902012-01-19 13:12:13 -080080 protected final static int DEFAULT_GENERATOR_FEATURE_FLAGS = JsonGenerator.Feature.collectDefaults();
Tatu Salorantaf15531c2011-12-22 23:00:40 -080081
Tatu Salorantae6dfc692012-09-28 15:34:05 -070082 private final static SerializableString DEFAULT_ROOT_VALUE_SEPARATOR = DefaultPrettyPrinter.DEFAULT_ROOT_VALUE_SEPARATOR;
83
Tatu07351902012-01-19 13:12:13 -080084 /**
85 * Enumeration that defines all on/off features that can only be
86 * changed for {@link JsonFactory}.
87 */
88 public enum Feature {
89
90 // // // Symbol handling (interning etc)
91
92 /**
93 * Feature that determines whether JSON object field names are
94 * to be canonicalized using {@link String#intern} or not:
95 * if enabled, all field names will be intern()ed (and caller
96 * can count on this being true for all such names); if disabled,
97 * no intern()ing is done. There may still be basic
98 * canonicalization (that is, same String will be used to represent
99 * all identical object property names for a single document).
100 *<p>
101 * Note: this setting only has effect if
102 * {@link #CANONICALIZE_FIELD_NAMES} is true -- otherwise no
103 * canonicalization of any sort is done.
104 *<p>
105 * This setting is enabled by default.
106 */
107 INTERN_FIELD_NAMES(true),
108
109 /**
110 * Feature that determines whether JSON object field names are
111 * to be canonicalized (details of how canonicalization is done
112 * then further specified by
113 * {@link #INTERN_FIELD_NAMES}).
114 *<p>
115 * This setting is enabled by default.
116 */
117 CANONICALIZE_FIELD_NAMES(true)
118
119 ;
120
121 /**
122 * Whether feature is enabled or disabled by default.
123 */
124 private final boolean _defaultState;
125
126 /**
127 * Method that calculates bit set (flags) of all features that
128 * are enabled by default.
129 */
130 public static int collectDefaults()
131 {
132 int flags = 0;
133 for (Feature f : values()) {
134 if (f.enabledByDefault()) {
135 flags |= f.getMask();
136 }
137 }
138 return flags;
139 }
140
141 private Feature(boolean defaultState)
142 {
143 _defaultState = defaultState;
144 }
145
146 public boolean enabledByDefault() { return _defaultState; }
147
148 public boolean enabledIn(int flags) { return (flags & getMask()) != 0; }
149
150 public int getMask() { return (1 << ordinal()); }
151 }
Tatu Salorantaf15531c2011-12-22 23:00:40 -0800152 /*
153 /**********************************************************
154 /* Buffer, symbol table management
155 /**********************************************************
156 */
157
158 /**
Tatu Saloranta10c3ec82012-09-05 19:38:49 -0700159 * This <code>ThreadLocal</code> contains a {@link java.lang.ref.SoftReference}
Tatu Salorantaf15531c2011-12-22 23:00:40 -0800160 * to a {@link BufferRecycler} used to provide a low-cost
161 * buffer recycling between reader and writer instances.
162 */
163 final protected static ThreadLocal<SoftReference<BufferRecycler>> _recyclerRef
164 = new ThreadLocal<SoftReference<BufferRecycler>>();
165
166 /**
167 * Each factory comes equipped with a shared root symbol table.
168 * It should not be linked back to the original blueprint, to
169 * avoid contents from leaking between factories.
170 */
Tatu Saloranta95f76a42012-10-05 13:04:23 -0700171 protected final transient CharsToNameCanonicalizer _rootCharSymbols = CharsToNameCanonicalizer.createRoot();
Tatu Salorantaf15531c2011-12-22 23:00:40 -0800172
173 /**
174 * Alternative to the basic symbol table, some stream-based
175 * parsers use different name canonicalization method.
176 *<p>
177 * TODO: should clean up this; looks messy having 2 alternatives
178 * with not very clear differences.
179 */
Tatu Saloranta95f76a42012-10-05 13:04:23 -0700180 protected final transient BytesToNameCanonicalizer _rootByteSymbols = BytesToNameCanonicalizer.createRoot();
Tatu Salorantaf15531c2011-12-22 23:00:40 -0800181
182 /*
183 /**********************************************************
184 /* Configuration
185 /**********************************************************
186 */
187
188 /**
189 * Object that implements conversion functionality between
190 * Java objects and JSON content. For base JsonFactory implementation
191 * usually not set by default, but can be explicitly set.
192 * Sub-classes (like @link org.codehaus.jackson.map.MappingJsonFactory}
193 * usually provide an implementation.
194 */
195 protected ObjectCodec _objectCodec;
196
197 /**
Tatu07351902012-01-19 13:12:13 -0800198 * Currently enabled factory features.
199 */
200 protected int _factoryFeatures = DEFAULT_FACTORY_FEATURE_FLAGS;
201
202 /**
Tatu Salorantaf15531c2011-12-22 23:00:40 -0800203 * Currently enabled parser features.
204 */
205 protected int _parserFeatures = DEFAULT_PARSER_FEATURE_FLAGS;
206
207 /**
208 * Currently enabled generator features.
209 */
210 protected int _generatorFeatures = DEFAULT_GENERATOR_FEATURE_FLAGS;
211
212 /**
213 * Definition of custom character escapes to use for generators created
214 * by this factory, if any. If null, standard data format specific
215 * escapes are used.
216 */
217 protected CharacterEscapes _characterEscapes;
218
219 /**
220 * Optional helper object that may decorate input sources, to do
221 * additional processing on input during parsing.
222 */
223 protected InputDecorator _inputDecorator;
224
225 /**
226 * Optional helper object that may decorate output object, to do
227 * additional processing on output during content generation.
228 */
229 protected OutputDecorator _outputDecorator;
Tatu Salorantae6dfc692012-09-28 15:34:05 -0700230
231 /**
232 * Separator used between root-level values, if any; null indicates
233 * "do not add separator".
234 * Default separator is a single space character.
235 *
236 * @since 2.1
237 */
238 protected SerializableString _rootValueSeparator = DEFAULT_ROOT_VALUE_SEPARATOR;
Tatu Salorantaf15531c2011-12-22 23:00:40 -0800239
240 /*
241 /**********************************************************
242 /* Construction
243 /**********************************************************
244 */
245
246 /**
247 * Default constructor used to create factory instances.
248 * Creation of a factory instance is a light-weight operation,
249 * but it is still a good idea to reuse limited number of
250 * factory instances (and quite often just a single instance):
251 * factories are used as context for storing some reused
252 * processing objects (such as symbol tables parsers use)
253 * and this reuse only works within context of a single
254 * factory instance.
255 */
256 public JsonFactory() { this(null); }
257
258 public JsonFactory(ObjectCodec oc) { _objectCodec = oc; }
259
Tatu Saloranta378ecdc2012-08-04 16:27:27 -0700260 /**
261 * Method for constructing a new {@link JsonFactory} that has
262 * the same settings as this instance, but is otherwise
263 * independent (i.e. nothing is actually shared, symbol tables
264 * are separate).
265 * Note that {@link ObjectCodec} reference is not copied but is
266 * set to null; caller typically needs to set it after calling
267 * this method.
268 *
269 * @since 2.1
270 */
271 public JsonFactory copy()
272 {
273 _checkInvalidCopy(JsonFactory.class);
274 return new JsonFactory(null);
275 }
276
277 /**
278 * @since 2.1
279 * @param exp
280 */
281 protected void _checkInvalidCopy(Class<?> exp)
282 {
283 if (getClass() != exp) {
284 throw new IllegalStateException("Failed copy(): "+getClass().getName()
285 +" (version: "+version()+") does not override copy(); it has to");
286 }
287 }
Tatu Saloranta95f76a42012-10-05 13:04:23 -0700288
289 /*
290 /**********************************************************
291 /* Serializable overrides
292 /**********************************************************
293 */
294
295 /**
296 * Method that we need to override to actually make restoration go
297 * through constructors etc.
298 * Also: must be overridden by sub-classes as well.
299 */
300 protected Object readResolve() {
301 return new JsonFactory(_objectCodec);
302 }
Tatu Saloranta378ecdc2012-08-04 16:27:27 -0700303
Tatu Salorantaf15531c2011-12-22 23:00:40 -0800304 /*
305 /**********************************************************
306 /* Format detection functionality (since 1.8)
307 /**********************************************************
308 */
309
310 /**
Tatu Saloranta1bdf0262012-08-24 14:43:17 -0700311 * Method that can be used to quickly check whether given schema
312 * is something that parsers and/or generators constructed by this
313 * factory could use. Note that this means possible use, at the level
314 * of data format (i.e. schema is for same data format as parsers and
315 * generators this factory constructs); individual schema instances
316 * may have further usage restrictions.
317 *
318 * @since 2.1
319 */
320 public boolean canUseSchema(FormatSchema schema) {
321 String ourFormat = getFormatName();
322 return (ourFormat != null) && ourFormat.equals(schema.getSchemaType());
323 }
324
325 /**
Tatu Salorantaf15531c2011-12-22 23:00:40 -0800326 * Method that returns short textual id identifying format
327 * this factory supports.
328 *<p>
329 * Note: sub-classes should override this method; default
330 * implementation will return null for all sub-classes
331 */
332 public String getFormatName()
333 {
334 /* Somewhat nasty check: since we can't make this abstract
335 * (due to backwards compatibility concerns), need to prevent
336 * format name "leakage"
337 */
338 if (getClass() == JsonFactory.class) {
339 return FORMAT_NAME_JSON;
340 }
341 return null;
342 }
343
344 public MatchStrength hasFormat(InputAccessor acc) throws IOException
345 {
346 // since we can't keep this abstract, only implement for "vanilla" instance
347 if (getClass() == JsonFactory.class) {
348 return hasJSONFormat(acc);
349 }
350 return null;
351 }
352
Tatu Salorantaad2df5f2012-08-22 20:55:49 -0700353 /**
354 * Method that can be called to determine if a custom
355 * {@link ObjectCodec} is needed for binding data parsed
356 * using {@link JsonParser} constructed by this factory
357 * (which typically also implies the same for serialization
358 * with {@link JsonGenerator}).
359 *
360 * @return True if custom codec is needed with parsers and
361 * generators created by this factory; false if a general
362 * {@link ObjectCodec} is enough
363 *
364 * @since 2.1
365 */
366 public boolean requiresCustomCodec() {
367 return false;
368 }
369
370 /**
371 * Helper method that can be called to determine if content accessed
372 * using given accessor seems to be JSON content.
373 */
Tatu Salorantaf15531c2011-12-22 23:00:40 -0800374 protected MatchStrength hasJSONFormat(InputAccessor acc) throws IOException
375 {
376 return ByteSourceJsonBootstrapper.hasJSONFormat(acc);
Tatu Salorantaad2df5f2012-08-22 20:55:49 -0700377 }
378
Tatu Salorantaf15531c2011-12-22 23:00:40 -0800379 /*
380 /**********************************************************
381 /* Versioned
382 /**********************************************************
383 */
384
Tatu Salorantae9b48512012-04-17 10:22:07 -0700385// @Override
Tatu Salorantaf15531c2011-12-22 23:00:40 -0800386 public Version version() {
Tatu Saloranta5a1bd992011-12-28 23:18:23 -0800387 return CoreVersion.instance.version();
Tatu Salorantaf15531c2011-12-22 23:00:40 -0800388 }
389
390 /*
391 /**********************************************************
Tatu07351902012-01-19 13:12:13 -0800392 /* Configuration, factory features
Tatu Salorantaf15531c2011-12-22 23:00:40 -0800393 /**********************************************************
394 */
395
396 /**
397 * Method for enabling or disabling specified parser feature
398 * (check {@link JsonParser.Feature} for list of features)
399 */
Tatu07351902012-01-19 13:12:13 -0800400 public final JsonFactory configure(JsonFactory.Feature f, boolean state) {
401 return state ? enable(f) : disable(f);
402 }
403
404 /**
405 * Method for enabling specified parser feature
406 * (check {@link JsonFactory.Feature} for list of features)
407 */
408 public JsonFactory enable(JsonFactory.Feature f) {
409 _factoryFeatures |= f.getMask();
Tatu Salorantaf15531c2011-12-22 23:00:40 -0800410 return this;
411 }
412
413 /**
Tatu07351902012-01-19 13:12:13 -0800414 * Method for disabling specified parser features
415 * (check {@link JsonFactory.Feature} for list of features)
416 */
417 public JsonFactory disable(JsonFactory.Feature f) {
418 _factoryFeatures &= ~f.getMask();
419 return this;
420 }
421
422 /**
423 * Checked whether specified parser feature is enabled.
424 */
425 public final boolean isEnabled(JsonFactory.Feature f) {
426 return (_factoryFeatures & f.getMask()) != 0;
427 }
428
429 /*
430 /**********************************************************
431 /* Configuration, parser configuration
432 /**********************************************************
433 */
434
435 /**
436 * Method for enabling or disabling specified parser feature
437 * (check {@link JsonParser.Feature} for list of features)
438 */
439 public final JsonFactory configure(JsonParser.Feature f, boolean state) {
440 return state ? enable(f) : disable(f);
441 }
442
443 /**
Tatu Salorantaf15531c2011-12-22 23:00:40 -0800444 * Method for enabling specified parser feature
445 * (check {@link JsonParser.Feature} for list of features)
446 */
447 public JsonFactory enable(JsonParser.Feature f) {
448 _parserFeatures |= f.getMask();
449 return this;
450 }
451
452 /**
453 * Method for disabling specified parser features
454 * (check {@link JsonParser.Feature} for list of features)
455 */
456 public JsonFactory disable(JsonParser.Feature f) {
457 _parserFeatures &= ~f.getMask();
458 return this;
459 }
460
461 /**
462 * Checked whether specified parser feature is enabled.
463 */
464 public final boolean isEnabled(JsonParser.Feature f) {
465 return (_parserFeatures & f.getMask()) != 0;
466 }
467
468 /**
469 * Method for getting currently configured input decorator (if any;
470 * there is no default decorator).
471 */
472 public InputDecorator getInputDecorator() {
473 return _inputDecorator;
474 }
475
476 /**
477 * Method for overriding currently configured input decorator
478 */
479 public JsonFactory setInputDecorator(InputDecorator d) {
480 _inputDecorator = d;
481 return this;
482 }
483
484 /*
485 /**********************************************************
486 /* Configuration, generator settings
487 /**********************************************************
488 */
489
490 /**
491 * Method for enabling or disabling specified generator feature
492 * (check {@link JsonGenerator.Feature} for list of features)
493 */
494 public final JsonFactory configure(JsonGenerator.Feature f, boolean state) {
Tatu07351902012-01-19 13:12:13 -0800495 return state ? enable(f) : disable(f);
Tatu Salorantaf15531c2011-12-22 23:00:40 -0800496 }
497
498
499 /**
500 * Method for enabling specified generator features
501 * (check {@link JsonGenerator.Feature} for list of features)
502 */
503 public JsonFactory enable(JsonGenerator.Feature f) {
504 _generatorFeatures |= f.getMask();
505 return this;
506 }
507
508 /**
509 * Method for disabling specified generator feature
510 * (check {@link JsonGenerator.Feature} for list of features)
511 */
512 public JsonFactory disable(JsonGenerator.Feature f) {
513 _generatorFeatures &= ~f.getMask();
514 return this;
515 }
516
517 /**
518 * Check whether specified generator feature is enabled.
519 */
520 public final boolean isEnabled(JsonGenerator.Feature f) {
521 return (_generatorFeatures & f.getMask()) != 0;
522 }
523
524 /**
525 * Method for accessing custom escapes factory uses for {@link JsonGenerator}s
526 * it creates.
527 */
528 public CharacterEscapes getCharacterEscapes() {
529 return _characterEscapes;
530 }
531
532 /**
533 * Method for defining custom escapes factory uses for {@link JsonGenerator}s
534 * it creates.
535 */
536 public JsonFactory setCharacterEscapes(CharacterEscapes esc) {
537 _characterEscapes = esc;
538 return this;
539 }
540
541 /**
542 * Method for getting currently configured output decorator (if any;
543 * there is no default decorator).
544 */
545 public OutputDecorator getOutputDecorator() {
546 return _outputDecorator;
547 }
548
549 /**
550 * Method for overriding currently configured output decorator
551 */
552 public JsonFactory setOutputDecorator(OutputDecorator d) {
553 _outputDecorator = d;
554 return this;
555 }
Tatu Salorantae6dfc692012-09-28 15:34:05 -0700556
557 /**
558 * Method that allows overriding String used for separating root-level
559 * JSON values (default is single space character)
560 *
561 * @param sep Separator to use, if any; null means that no separator is
562 * automatically added
563 *
564 * @since 2.1
565 */
566 public JsonFactory setRootValueSeparator(String sep) {
567 _rootValueSeparator = (sep == null) ? null : new SerializedString(sep);
568 return this;
569 }
570
571 /**
572 * @since 2.1
573 */
574 public String getRootValueSeparator() {
575 return (_rootValueSeparator == null) ? null : _rootValueSeparator.getValue();
576 }
Tatu Salorantaf15531c2011-12-22 23:00:40 -0800577
578 /*
579 /**********************************************************
580 /* Configuration, other
581 /**********************************************************
582 */
583
584 /**
585 * Method for associating a {@link ObjectCodec} (typically
Tatu Salorantad77350e2011-12-22 23:13:13 -0800586 * a <code>com.fasterxml.jackson.databind.ObjectMapper</code>)
587 * with this factory (and more importantly, parsers and generators
Tatu Salorantaf15531c2011-12-22 23:00:40 -0800588 * it constructs). This is needed to use data-binding methods
589 * of {@link JsonParser} and {@link JsonGenerator} instances.
590 */
591 public JsonFactory setCodec(ObjectCodec oc) {
592 _objectCodec = oc;
593 return this;
594 }
595
596 public ObjectCodec getCodec() { return _objectCodec; }
597
598 /*
599 /**********************************************************
Tatu Salorantafeaabd12012-07-22 23:03:41 -0700600 /* Parser factories (new ones, as per [Issue-25])
Tatu Salorantaf15531c2011-12-22 23:00:40 -0800601 /**********************************************************
602 */
603
604 /**
605 * Method for constructing JSON parser instance to parse
606 * contents of specified file. Encoding is auto-detected
607 * from contents according to JSON specification recommended
608 * mechanism.
609 *<p>
610 * Underlying input stream (needed for reading contents)
611 * will be <b>owned</b> (and managed, i.e. closed as need be) by
612 * the parser, since caller has no access to it.
613 *
614 * @param f File that contains JSON content to parse
Tatu Salorantafeaabd12012-07-22 23:03:41 -0700615 *
616 * @since 2.1
617 */
618 public JsonParser createParser(File f)
619 throws IOException, JsonParseException
620 {
621 // Must delegate to old version, until 2.2
622 // TODO: change direction in 2.2; after ensuring impls support new method
623 return createJsonParser(f);
624 }
625
626 /**
627 * Method for constructing JSON parser instance to parse
628 * contents of resource reference by given URL.
629 * Encoding is auto-detected
630 * from contents according to JSON specification recommended
631 * mechanism.
632 *<p>
633 * Underlying input stream (needed for reading contents)
634 * will be <b>owned</b> (and managed, i.e. closed as need be) by
635 * the parser, since caller has no access to it.
636 *
637 * @param url URL pointing to resource that contains JSON content to parse
638 *
639 * @since 2.1
640 */
641 public JsonParser createParser(URL url)
642 throws IOException, JsonParseException
643 {
644 // Must delegate to old version, until 2.2
645 // TODO: change direction in 2.2; after ensuring impls support new method
646 return createJsonParser(url);
647 }
648
649 /**
650 * Method for constructing JSON parser instance to parse
651 * the contents accessed via specified input stream.
652 *<p>
653 * The input stream will <b>not be owned</b> by
654 * the parser, it will still be managed (i.e. closed if
655 * end-of-stream is reacher, or parser close method called)
656 * if (and only if) {@link com.fasterxml.jackson.core.JsonParser.Feature#AUTO_CLOSE_SOURCE}
657 * is enabled.
658 *<p>
659 * Note: no encoding argument is taken since it can always be
660 * auto-detected as suggested by JSON RFC.
661 *
662 * @param in InputStream to use for reading JSON content to parse
663 *
664 * @since 2.1
665 */
666 public JsonParser createParser(InputStream in)
667 throws IOException, JsonParseException
668 {
669 // Must delegate to old version, until 2.2
670 // TODO: change direction in 2.2; after ensuring impls support new method
671 return createJsonParser(in);
672 }
673
674 /**
675 * Method for constructing parser for parsing
676 * the contents accessed via specified Reader.
677 <p>
678 * The read stream will <b>not be owned</b> by
679 * the parser, it will still be managed (i.e. closed if
680 * end-of-stream is reacher, or parser close method called)
681 * if (and only if) {@link com.fasterxml.jackson.core.JsonParser.Feature#AUTO_CLOSE_SOURCE}
682 * is enabled.
683 *
684 * @param r Reader to use for reading JSON content to parse
685 *
686 * @since 2.1
687 */
688 public JsonParser createParser(Reader r)
689 throws IOException, JsonParseException
690 {
691 // Must delegate to old version, until 2.2
692 // TODO: change direction in 2.2; after ensuring impls support new method
693 return createJsonParser(r);
694 }
695
696 /**
697 * Method for constructing parser for parsing
698 * the contents of given byte array.
699 *
700 * @since 2.1
701 */
702 public JsonParser createParser(byte[] data)
703 throws IOException, JsonParseException
704 {
705 // Must delegate to old version, until 2.2
706 // TODO: change direction in 2.2; after ensuring impls support new method
707 return createJsonParser(data);
708 }
709
710 /**
711 * Method for constructing parser for parsing
712 * the contents of given byte array.
713 *
714 * @param data Buffer that contains data to parse
715 * @param offset Offset of the first data byte within buffer
716 * @param len Length of contents to parse within buffer
717 *
718 * @since 2.1
719 */
720 public JsonParser createParser(byte[] data, int offset, int len)
721 throws IOException, JsonParseException
722 {
723 // Must delegate to old version, until 2.2
724 // TODO: change direction in 2.2; after ensuring impls support new method
725 return createJsonParser(data, offset, len);
726 }
727
728 /**
729 * Method for constructing parser for parsing
730 * contents of given String.
731 *
732 * @since 2.1
733 */
734 public JsonParser createParser(String content)
735 throws IOException, JsonParseException
736 {
737 // Must delegate to old version, until 2.2
738 // TODO: change direction in 2.2; after ensuring impls support new method
739 return createJsonParser(content);
740 }
741
742 /*
743 /**********************************************************
744 /* Parser factories (old ones, as per [Issue-25])
745 /**********************************************************
746 */
747
748 /**
749 * Method for constructing JSON parser instance to parse
750 * contents of specified file. Encoding is auto-detected
751 * from contents according to JSON specification recommended
752 * mechanism.
753 *<p>
754 * Underlying input stream (needed for reading contents)
755 * will be <b>owned</b> (and managed, i.e. closed as need be) by
756 * the parser, since caller has no access to it.
757 *<p>
758 * NOTE: as of 2.1, should not be used (will be deprecated in 2.2);
759 * instead, should call <code>createParser</code>.
760 *
761 * @param f File that contains JSON content to parse
Tatu Salorantaf15531c2011-12-22 23:00:40 -0800762 */
763 public JsonParser createJsonParser(File f)
764 throws IOException, JsonParseException
765 {
766 // true, since we create InputStream from File
767 IOContext ctxt = _createContext(f, true);
768 InputStream in = new FileInputStream(f);
769 // [JACKSON-512]: allow wrapping with InputDecorator
770 if (_inputDecorator != null) {
771 in = _inputDecorator.decorate(ctxt, in);
772 }
Tatu Salorantaeeb2fbd2012-05-28 22:00:08 -0700773 return _createParser(in, ctxt);
Tatu Salorantaf15531c2011-12-22 23:00:40 -0800774 }
775
776 /**
777 * Method for constructing JSON parser instance to parse
778 * contents of resource reference by given URL.
779 * Encoding is auto-detected
780 * from contents according to JSON specification recommended
781 * mechanism.
782 *<p>
783 * Underlying input stream (needed for reading contents)
784 * will be <b>owned</b> (and managed, i.e. closed as need be) by
785 * the parser, since caller has no access to it.
Tatu Salorantafeaabd12012-07-22 23:03:41 -0700786 *<p>
787 * NOTE: as of 2.1, should not be used (will be deprecated in 2.2);
788 * instead, should call <code>createParser</code>.
Tatu Salorantaf15531c2011-12-22 23:00:40 -0800789 *
790 * @param url URL pointing to resource that contains JSON content to parse
791 */
792 public JsonParser createJsonParser(URL url)
793 throws IOException, JsonParseException
794 {
795 // true, since we create InputStream from URL
796 IOContext ctxt = _createContext(url, true);
797 InputStream in = _optimizedStreamFromURL(url);
798 // [JACKSON-512]: allow wrapping with InputDecorator
799 if (_inputDecorator != null) {
800 in = _inputDecorator.decorate(ctxt, in);
801 }
Tatu Salorantaeeb2fbd2012-05-28 22:00:08 -0700802 return _createParser(in, ctxt);
Tatu Salorantaf15531c2011-12-22 23:00:40 -0800803 }
804
805 /**
806 * Method for constructing JSON parser instance to parse
807 * the contents accessed via specified input stream.
808 *<p>
809 * The input stream will <b>not be owned</b> by
810 * the parser, it will still be managed (i.e. closed if
811 * end-of-stream is reacher, or parser close method called)
812 * if (and only if) {@link com.fasterxml.jackson.core.JsonParser.Feature#AUTO_CLOSE_SOURCE}
813 * is enabled.
814 *<p>
815 * Note: no encoding argument is taken since it can always be
Tatu Salorantafeaabd12012-07-22 23:03:41 -0700816 * auto-detected as suggested by JSON RFC.
817 *<p>
818 * NOTE: as of 2.1, should not be used (will be deprecated in 2.2);
819 * instead, should call <code>createParser</code>.
Tatu Salorantaf15531c2011-12-22 23:00:40 -0800820 *
821 * @param in InputStream to use for reading JSON content to parse
822 */
823 public JsonParser createJsonParser(InputStream in)
824 throws IOException, JsonParseException
825 {
826 IOContext ctxt = _createContext(in, false);
827 // [JACKSON-512]: allow wrapping with InputDecorator
828 if (_inputDecorator != null) {
829 in = _inputDecorator.decorate(ctxt, in);
830 }
Tatu Salorantaeeb2fbd2012-05-28 22:00:08 -0700831 return _createParser(in, ctxt);
Tatu Salorantaf15531c2011-12-22 23:00:40 -0800832 }
833
834 /**
835 * Method for constructing parser for parsing
836 * the contents accessed via specified Reader.
837 <p>
838 * The read stream will <b>not be owned</b> by
839 * the parser, it will still be managed (i.e. closed if
840 * end-of-stream is reacher, or parser close method called)
841 * if (and only if) {@link com.fasterxml.jackson.core.JsonParser.Feature#AUTO_CLOSE_SOURCE}
842 * is enabled.
843 *<p>
Tatu Salorantafeaabd12012-07-22 23:03:41 -0700844 * NOTE: as of 2.1, should not be used (will be deprecated in 2.2);
845 * instead, should call <code>createParser</code>.
Tatu Salorantaf15531c2011-12-22 23:00:40 -0800846 *
847 * @param r Reader to use for reading JSON content to parse
848 */
849 public JsonParser createJsonParser(Reader r)
850 throws IOException, JsonParseException
851 {
852 // false -> we do NOT own Reader (did not create it)
853 IOContext ctxt = _createContext(r, false);
854 // [JACKSON-512]: allow wrapping with InputDecorator
855 if (_inputDecorator != null) {
856 r = _inputDecorator.decorate(ctxt, r);
857 }
Tatu Saloranta3e5ff6d2012-06-27 18:46:43 -0700858 return _createParser(r, ctxt);
Tatu Salorantaf15531c2011-12-22 23:00:40 -0800859 }
860
861 /**
862 * Method for constructing parser for parsing
863 * the contents of given byte array.
Tatu Salorantafeaabd12012-07-22 23:03:41 -0700864 *<p>
865 * NOTE: as of 2.1, should not be used (will be deprecated in 2.2);
866 * instead, should call <code>createParser</code>.
Tatu Salorantaf15531c2011-12-22 23:00:40 -0800867 */
868 public JsonParser createJsonParser(byte[] data)
869 throws IOException, JsonParseException
870 {
871 IOContext ctxt = _createContext(data, true);
872 // [JACKSON-512]: allow wrapping with InputDecorator
873 if (_inputDecorator != null) {
874 InputStream in = _inputDecorator.decorate(ctxt, data, 0, data.length);
875 if (in != null) {
Tatu Salorantaeeb2fbd2012-05-28 22:00:08 -0700876 return _createParser(in, ctxt);
Tatu Salorantaf15531c2011-12-22 23:00:40 -0800877 }
878 }
Tatu Salorantaeeb2fbd2012-05-28 22:00:08 -0700879 return _createParser(data, 0, data.length, ctxt);
Tatu Salorantaf15531c2011-12-22 23:00:40 -0800880 }
881
882 /**
883 * Method for constructing parser for parsing
884 * the contents of given byte array.
Tatu Salorantafeaabd12012-07-22 23:03:41 -0700885 *<p>
886 * NOTE: as of 2.1, should not be used (will be deprecated in 2.2);
887 * instead, should call <code>createParser</code>.
Tatu Salorantaf15531c2011-12-22 23:00:40 -0800888 *
889 * @param data Buffer that contains data to parse
890 * @param offset Offset of the first data byte within buffer
891 * @param len Length of contents to parse within buffer
892 */
893 public JsonParser createJsonParser(byte[] data, int offset, int len)
894 throws IOException, JsonParseException
895 {
896 IOContext ctxt = _createContext(data, true);
897 // [JACKSON-512]: allow wrapping with InputDecorator
898 if (_inputDecorator != null) {
899 InputStream in = _inputDecorator.decorate(ctxt, data, offset, len);
900 if (in != null) {
Tatu Salorantaeeb2fbd2012-05-28 22:00:08 -0700901 return _createParser(in, ctxt);
Tatu Salorantaf15531c2011-12-22 23:00:40 -0800902 }
903 }
Tatu Salorantaeeb2fbd2012-05-28 22:00:08 -0700904 return _createParser(data, offset, len, ctxt);
Tatu Salorantaf15531c2011-12-22 23:00:40 -0800905 }
906
907 /**
908 * Method for constructing parser for parsing
909 * contents of given String.
Tatu Salorantafeaabd12012-07-22 23:03:41 -0700910 *<p>
911 * NOTE: as of 2.1, should not be used (will be deprecated in 2.2);
912 * instead, should call <code>createParser</code>.
Tatu Salorantaf15531c2011-12-22 23:00:40 -0800913 */
914 public JsonParser createJsonParser(String content)
915 throws IOException, JsonParseException
916 {
Tatu Saloranta3e5ff6d2012-06-27 18:46:43 -0700917 Reader r = new StringReader(content);
Tatu Salorantaf15531c2011-12-22 23:00:40 -0800918 // true -> we own the Reader (and must close); not a big deal
919 IOContext ctxt = _createContext(r, true);
920 // [JACKSON-512]: allow wrapping with InputDecorator
921 if (_inputDecorator != null) {
922 r = _inputDecorator.decorate(ctxt, r);
923 }
Tatu Saloranta3e5ff6d2012-06-27 18:46:43 -0700924 return _createParser(r, ctxt);
Tatu Salorantaf15531c2011-12-22 23:00:40 -0800925 }
926
927 /*
928 /**********************************************************
Tatu Salorantafeaabd12012-07-22 23:03:41 -0700929 /* Generator factories, new (as per [Issue-25]
Tatu Salorantaf15531c2011-12-22 23:00:40 -0800930 /**********************************************************
931 */
932
933 /**
934 * Method for constructing JSON generator for writing JSON content
935 * using specified output stream.
936 * Encoding to use must be specified, and needs to be one of available
937 * types (as per JSON specification).
938 *<p>
939 * Underlying stream <b>is NOT owned</b> by the generator constructed,
940 * so that generator will NOT close the output stream when
941 * {@link JsonGenerator#close} is called (unless auto-closing
942 * feature,
943 * {@link com.fasterxml.jackson.core.JsonGenerator.Feature#AUTO_CLOSE_TARGET}
944 * is enabled).
945 * Using application needs to close it explicitly if this is the case.
946 *<p>
947 * Note: there are formats that use fixed encoding (like most binary data formats)
948 * and that ignore passed in encoding.
Tatu Salorantafeaabd12012-07-22 23:03:41 -0700949 *<p>
950 * NOTE: starting with 2.1, should not be used (will be deprecated in 2.2);
951 * instead, should call <code>createGenerator</code>.
952 *
953 * @since 2.1 Will eventually replace <code>createJsonGenerator</code> variant.
954 *
955 * @param out OutputStream to use for writing JSON content
956 * @param enc Character encoding to use
957 */
958 public JsonGenerator createGenerator(OutputStream out, JsonEncoding enc)
959 throws IOException
960 {
961 return createJsonGenerator(out, enc);
962 }
963
964 /**
965 * Method for constructing JSON generator for writing JSON content
966 * using specified Writer.
967 *<p>
968 * Underlying stream <b>is NOT owned</b> by the generator constructed,
969 * so that generator will NOT close the Reader when
970 * {@link JsonGenerator#close} is called (unless auto-closing
971 * feature,
972 * {@link com.fasterxml.jackson.core.JsonGenerator.Feature#AUTO_CLOSE_TARGET} is enabled).
973 * Using application needs to close it explicitly.
974 *<p>
975 * NOTE: starting with 2.1, should not be used (will be deprecated in 2.2);
976 * instead, should call <code>createGenerator</code>.
977 *
978 * @since 2.1 Will eventually replace <code>createJsonGenerator</code> variant.
979 *
980 * @param out Writer to use for writing JSON content
981 */
982 public JsonGenerator createGenerator(Writer out)
983 throws IOException
984 {
985 return createJsonGenerator(out);
986 }
987
988 /**
989 * Convenience method for constructing generator that uses default
990 * encoding of the format (UTF-8 for JSON and most other data formats).
991 *<p>
992 * Note: there are formats that use fixed encoding (like most binary data formats).
993 *<p>
994 * NOTE: starting with 2.1, should not be used (will be deprecated in 2.2);
995 * instead, should call <code>createGenerator</code>.
996 *
997 * @since 2.1 Will eventually replace <code>createJsonGenerator</code> variant.
998 */
999 public JsonGenerator createGenerator(OutputStream out) throws IOException {
1000 return createJsonGenerator(out);
1001 }
1002
1003 /**
1004 * Method for constructing JSON generator for writing JSON content
1005 * to specified file, overwriting contents it might have (or creating
1006 * it if such file does not yet exist).
1007 * Encoding to use must be specified, and needs to be one of available
1008 * types (as per JSON specification).
1009 *<p>
1010 * Underlying stream <b>is owned</b> by the generator constructed,
1011 * i.e. generator will handle closing of file when
1012 * {@link JsonGenerator#close} is called.
1013 *<p>
1014 * NOTE: starting with 2.1, should not be used (will be deprecated in 2.2);
1015 * instead, should call <code>createGenerator</code>.
1016 *
1017 * @since 2.1 Will eventually replace <code>createJsonGenerator</code> variant.
1018 *
1019 * @param f File to write contents to
1020 * @param enc Character encoding to use
1021 */
1022 public JsonGenerator createGenerator(File f, JsonEncoding enc)
1023 throws IOException
1024 {
1025 return createJsonGenerator(f, enc);
1026 }
1027
1028 /*
1029 /**********************************************************
1030 /* Generator factories, old (as per [Issue-25]
1031 /**********************************************************
1032 */
1033
1034 /**
1035 * Method for constructing JSON generator for writing JSON content
1036 * using specified output stream.
1037 * Encoding to use must be specified, and needs to be one of available
1038 * types (as per JSON specification).
1039 *<p>
1040 * Underlying stream <b>is NOT owned</b> by the generator constructed,
1041 * so that generator will NOT close the output stream when
1042 * {@link JsonGenerator#close} is called (unless auto-closing
1043 * feature,
1044 * {@link com.fasterxml.jackson.core.JsonGenerator.Feature#AUTO_CLOSE_TARGET}
1045 * is enabled).
1046 * Using application needs to close it explicitly if this is the case.
1047 *<p>
1048 * Note: there are formats that use fixed encoding (like most binary data formats)
1049 * and that ignore passed in encoding.
1050 *<p>
1051 * NOTE: starting with 2.1, should not be used (will be deprecated in 2.2);
1052 * instead, should call <code>createGenerator</code>.
Tatu Salorantaf15531c2011-12-22 23:00:40 -08001053 *
1054 * @param out OutputStream to use for writing JSON content
1055 * @param enc Character encoding to use
1056 */
1057 public JsonGenerator createJsonGenerator(OutputStream out, JsonEncoding enc)
1058 throws IOException
1059 {
1060 // false -> we won't manage the stream unless explicitly directed to
1061 IOContext ctxt = _createContext(out, false);
1062 ctxt.setEncoding(enc);
1063 if (enc == JsonEncoding.UTF8) {
1064 // [JACKSON-512]: allow wrapping with _outputDecorator
1065 if (_outputDecorator != null) {
1066 out = _outputDecorator.decorate(ctxt, out);
1067 }
1068 return _createUTF8JsonGenerator(out, ctxt);
1069 }
1070 Writer w = _createWriter(out, enc, ctxt);
1071 // [JACKSON-512]: allow wrapping with _outputDecorator
1072 if (_outputDecorator != null) {
1073 w = _outputDecorator.decorate(ctxt, w);
1074 }
Tatu Salorantaeeb2fbd2012-05-28 22:00:08 -07001075 return _createGenerator(w, ctxt);
Tatu Salorantaf15531c2011-12-22 23:00:40 -08001076 }
1077
1078 /**
1079 * Method for constructing JSON generator for writing JSON content
1080 * using specified Writer.
1081 *<p>
1082 * Underlying stream <b>is NOT owned</b> by the generator constructed,
1083 * so that generator will NOT close the Reader when
1084 * {@link JsonGenerator#close} is called (unless auto-closing
1085 * feature,
1086 * {@link com.fasterxml.jackson.core.JsonGenerator.Feature#AUTO_CLOSE_TARGET} is enabled).
1087 * Using application needs to close it explicitly.
Tatu Salorantafeaabd12012-07-22 23:03:41 -07001088 *<p>
1089 * NOTE: starting with 2.1, should not be used (will be deprecated in 2.2);
1090 * instead, should call <code>createGenerator</code>.
Tatu Salorantaf15531c2011-12-22 23:00:40 -08001091 *
1092 * @param out Writer to use for writing JSON content
1093 */
1094 public JsonGenerator createJsonGenerator(Writer out)
1095 throws IOException
1096 {
1097 IOContext ctxt = _createContext(out, false);
1098 // [JACKSON-512]: allow wrapping with _outputDecorator
1099 if (_outputDecorator != null) {
1100 out = _outputDecorator.decorate(ctxt, out);
1101 }
Tatu Salorantaeeb2fbd2012-05-28 22:00:08 -07001102 return _createGenerator(out, ctxt);
Tatu Salorantaf15531c2011-12-22 23:00:40 -08001103 }
1104
1105 /**
1106 * Convenience method for constructing generator that uses default
1107 * encoding of the format (UTF-8 for JSON and most other data formats).
1108 *<p>
1109 * Note: there are formats that use fixed encoding (like most binary data formats).
Tatu Salorantafeaabd12012-07-22 23:03:41 -07001110 *<p>
1111 * NOTE: starting with 2.1, should not be used (will be deprecated in 2.2);
1112 * instead, should call <code>createGenerator</code>.
Tatu Salorantaf15531c2011-12-22 23:00:40 -08001113 */
1114 public JsonGenerator createJsonGenerator(OutputStream out) throws IOException {
1115 return createJsonGenerator(out, JsonEncoding.UTF8);
1116 }
1117
1118 /**
1119 * Method for constructing JSON generator for writing JSON content
1120 * to specified file, overwriting contents it might have (or creating
1121 * it if such file does not yet exist).
1122 * Encoding to use must be specified, and needs to be one of available
1123 * types (as per JSON specification).
1124 *<p>
1125 * Underlying stream <b>is owned</b> by the generator constructed,
1126 * i.e. generator will handle closing of file when
1127 * {@link JsonGenerator#close} is called.
Tatu Salorantafeaabd12012-07-22 23:03:41 -07001128 *<p>
1129 * NOTE: starting with 2.1, should not be used (will be deprecated in 2.2);
1130 * instead, should call <code>createGenerator</code>.
Tatu Salorantaf15531c2011-12-22 23:00:40 -08001131 *
1132 * @param f File to write contents to
1133 * @param enc Character encoding to use
1134 */
1135 public JsonGenerator createJsonGenerator(File f, JsonEncoding enc)
1136 throws IOException
1137 {
1138 OutputStream out = new FileOutputStream(f);
1139 // true -> yes, we have to manage the stream since we created it
1140 IOContext ctxt = _createContext(out, true);
1141 ctxt.setEncoding(enc);
1142 if (enc == JsonEncoding.UTF8) {
1143 // [JACKSON-512]: allow wrapping with _outputDecorator
1144 if (_outputDecorator != null) {
1145 out = _outputDecorator.decorate(ctxt, out);
1146 }
1147 return _createUTF8JsonGenerator(out, ctxt);
1148 }
1149 Writer w = _createWriter(out, enc, ctxt);
1150 // [JACKSON-512]: allow wrapping with _outputDecorator
1151 if (_outputDecorator != null) {
1152 w = _outputDecorator.decorate(ctxt, w);
1153 }
Tatu Salorantaeeb2fbd2012-05-28 22:00:08 -07001154 return _createGenerator(w, ctxt);
Tatu Salorantaf15531c2011-12-22 23:00:40 -08001155 }
1156
1157 /*
1158 /**********************************************************
1159 /* Factory methods used by factory for creating parser instances,
1160 /* overridable by sub-classes
1161 /**********************************************************
1162 */
1163
1164 /**
1165 * Overridable factory method that actually instantiates desired parser
1166 * given {@link InputStream} and context object.
1167 *<p>
1168 * This method is specifically designed to remain
1169 * compatible between minor versions so that sub-classes can count
1170 * on it being called as expected. That is, it is part of official
1171 * interface from sub-class perspective, although not a public
1172 * method available to users of factory implementations.
Tatu Salorantaeeb2fbd2012-05-28 22:00:08 -07001173 *
1174 * @since 2.1
Tatu Salorantaf15531c2011-12-22 23:00:40 -08001175 */
Tatu Salorantaeeb2fbd2012-05-28 22:00:08 -07001176 protected JsonParser _createParser(InputStream in, IOContext ctxt)
Tatu Salorantaf15531c2011-12-22 23:00:40 -08001177 throws IOException, JsonParseException
1178 {
Tatu Salorantaeeb2fbd2012-05-28 22:00:08 -07001179 /* NOTE: MUST call the deprecated method until it is deleted, just so
1180 * that override still works as expected, for now.
1181 */
1182 return _createJsonParser(in, ctxt);
1183 }
1184
1185 /**
1186 * @deprecated since 2.1 -- use {@link #_createParser(InputStream, IOContext)} instead
1187 */
1188 @Deprecated
1189 protected JsonParser _createJsonParser(InputStream in, IOContext ctxt) throws IOException, JsonParseException {
Tatu07351902012-01-19 13:12:13 -08001190 // As per [JACKSON-259], may want to fully disable canonicalization:
Tatu Salorantaf15531c2011-12-22 23:00:40 -08001191 return new ByteSourceJsonBootstrapper(ctxt, in).constructParser(_parserFeatures,
Tatu07351902012-01-19 13:12:13 -08001192 _objectCodec, _rootByteSymbols, _rootCharSymbols,
1193 isEnabled(JsonFactory.Feature.CANONICALIZE_FIELD_NAMES),
1194 isEnabled(JsonFactory.Feature.INTERN_FIELD_NAMES));
Tatu Salorantaf15531c2011-12-22 23:00:40 -08001195 }
Tatu Salorantaeeb2fbd2012-05-28 22:00:08 -07001196
Tatu Salorantaf15531c2011-12-22 23:00:40 -08001197 /**
1198 * Overridable factory method that actually instantiates parser
1199 * using given {@link Reader} object for reading content.
1200 *<p>
1201 * This method is specifically designed to remain
1202 * compatible between minor versions so that sub-classes can count
1203 * on it being called as expected. That is, it is part of official
1204 * interface from sub-class perspective, although not a public
1205 * method available to users of factory implementations.
Tatu Salorantaeeb2fbd2012-05-28 22:00:08 -07001206 *
1207 * @since 2.1
Tatu Salorantaf15531c2011-12-22 23:00:40 -08001208 */
Tatu Salorantaeeb2fbd2012-05-28 22:00:08 -07001209 protected JsonParser _createParser(Reader r, IOContext ctxt)
1210 throws IOException, JsonParseException
Tatu Salorantaf15531c2011-12-22 23:00:40 -08001211 {
Tatu Salorantaeeb2fbd2012-05-28 22:00:08 -07001212 /* NOTE: MUST call the deprecated method until it is deleted, just so
1213 * that override still works as expected, for now.
1214 */
1215 return _createJsonParser(r, ctxt);
1216 }
1217
1218 /**
1219 * @deprecated since 2.1 -- use {@link #_createParser(Reader, IOContext)} instead
1220 */
1221 @Deprecated
1222 protected JsonParser _createJsonParser(Reader r, IOContext ctxt) throws IOException, JsonParseException {
Tatu Salorantaf15531c2011-12-22 23:00:40 -08001223 return new ReaderBasedJsonParser(ctxt, _parserFeatures, r, _objectCodec,
Tatu07351902012-01-19 13:12:13 -08001224 _rootCharSymbols.makeChild(isEnabled(JsonFactory.Feature.CANONICALIZE_FIELD_NAMES),
1225 isEnabled(JsonFactory.Feature.INTERN_FIELD_NAMES)));
Tatu Salorantaf15531c2011-12-22 23:00:40 -08001226 }
1227
1228 /**
1229 * Overridable factory method that actually instantiates parser
1230 * using given {@link Reader} object for reading content
1231 * passed as raw byte array.
1232 *<p>
1233 * This method is specifically designed to remain
1234 * compatible between minor versions so that sub-classes can count
1235 * on it being called as expected. That is, it is part of official
1236 * interface from sub-class perspective, although not a public
1237 * method available to users of factory implementations.
1238 */
Tatu Salorantaeeb2fbd2012-05-28 22:00:08 -07001239 protected JsonParser _createParser(byte[] data, int offset, int len, IOContext ctxt)
Tatu Salorantaf15531c2011-12-22 23:00:40 -08001240 throws IOException, JsonParseException
1241 {
Tatu Salorantaeeb2fbd2012-05-28 22:00:08 -07001242 /* NOTE: MUST call the deprecated method until it is deleted, just so
1243 * that override still works as expected, for now.
1244 */
1245 return _createJsonParser(data, offset, len, ctxt);
1246 }
1247
1248 /**
1249 * @deprecated since 2.1 -- use {@link #_createParser(byte[], int, int, IOContext)} instead
1250 */
1251 @Deprecated
1252 protected JsonParser _createJsonParser(byte[] data, int offset, int len, IOContext ctxt) throws IOException, JsonParseException {
Tatu Salorantaf15531c2011-12-22 23:00:40 -08001253 return new ByteSourceJsonBootstrapper(ctxt, data, offset, len).constructParser(_parserFeatures,
Tatu07351902012-01-19 13:12:13 -08001254 _objectCodec, _rootByteSymbols, _rootCharSymbols,
1255 isEnabled(JsonFactory.Feature.CANONICALIZE_FIELD_NAMES),
1256 isEnabled(JsonFactory.Feature.INTERN_FIELD_NAMES));
Tatu Salorantaf15531c2011-12-22 23:00:40 -08001257 }
Tatu Salorantaeeb2fbd2012-05-28 22:00:08 -07001258
Tatu Salorantaf15531c2011-12-22 23:00:40 -08001259 /*
1260 /**********************************************************
1261 /* Factory methods used by factory for creating generator instances,
1262 /* overridable by sub-classes
1263 /**********************************************************
1264 */
1265
1266 /**
1267 * Overridable factory method that actually instantiates generator for
1268 * given {@link Writer} and context object.
1269 *<p>
1270 * This method is specifically designed to remain
1271 * compatible between minor versions so that sub-classes can count
1272 * on it being called as expected. That is, it is part of official
1273 * interface from sub-class perspective, although not a public
1274 * method available to users of factory implementations.
1275 */
Tatu Salorantaeeb2fbd2012-05-28 22:00:08 -07001276 protected JsonGenerator _createGenerator(Writer out, IOContext ctxt)
1277 throws IOException
1278 {
1279 /* NOTE: MUST call the deprecated method until it is deleted, just so
1280 * that override still works as expected, for now.
1281 */
1282 return _createJsonGenerator(out, ctxt);
1283 }
1284
1285 /**
Tatu Salorantaec300272012-06-28 15:08:51 -07001286 * @deprecated since 2.1 -- use {@link #_createGenerator(Writer, IOContext)} instead
Tatu Salorantaeeb2fbd2012-05-28 22:00:08 -07001287 */
1288 @Deprecated
Tatu Salorantaf15531c2011-12-22 23:00:40 -08001289 protected JsonGenerator _createJsonGenerator(Writer out, IOContext ctxt)
1290 throws IOException
1291 {
Tatu Salorantae6dfc692012-09-28 15:34:05 -07001292 WriterBasedJsonGenerator gen = new WriterBasedJsonGenerator(ctxt,
1293 _generatorFeatures, _objectCodec, out);
Tatu Salorantaf15531c2011-12-22 23:00:40 -08001294 if (_characterEscapes != null) {
1295 gen.setCharacterEscapes(_characterEscapes);
1296 }
Tatu Salorantae6dfc692012-09-28 15:34:05 -07001297 SerializableString rootSep = _rootValueSeparator;
1298 if (rootSep != DEFAULT_ROOT_VALUE_SEPARATOR) {
1299 gen.setRootValueSeparator(rootSep);
1300 }
Tatu Salorantaf15531c2011-12-22 23:00:40 -08001301 return gen;
1302 }
1303
1304 /**
1305 * Overridable factory method that actually instantiates generator for
1306 * given {@link OutputStream} and context object, using UTF-8 encoding.
1307 *<p>
1308 * This method is specifically designed to remain
1309 * compatible between minor versions so that sub-classes can count
1310 * on it being called as expected. That is, it is part of official
1311 * interface from sub-class perspective, although not a public
1312 * method available to users of factory implementations.
1313 */
Tatu Salorantaeeb2fbd2012-05-28 22:00:08 -07001314 protected JsonGenerator _createUTF8Generator(OutputStream out, IOContext ctxt) throws IOException {
1315 return _createUTF8JsonGenerator(out, ctxt);
1316 }
1317
1318 /**
Tatu Salorantaec300272012-06-28 15:08:51 -07001319 * @deprecated since 2.1
Tatu Salorantaeeb2fbd2012-05-28 22:00:08 -07001320 */
1321 @Deprecated
Tatu Salorantaf15531c2011-12-22 23:00:40 -08001322 protected JsonGenerator _createUTF8JsonGenerator(OutputStream out, IOContext ctxt)
1323 throws IOException
1324 {
Tatu Salorantae6dfc692012-09-28 15:34:05 -07001325 UTF8JsonGenerator gen = new UTF8JsonGenerator(ctxt,
1326 _generatorFeatures, _objectCodec, out);
Tatu Salorantaf15531c2011-12-22 23:00:40 -08001327 if (_characterEscapes != null) {
1328 gen.setCharacterEscapes(_characterEscapes);
1329 }
Tatu Salorantae6dfc692012-09-28 15:34:05 -07001330 SerializableString rootSep = _rootValueSeparator;
1331 if (rootSep != DEFAULT_ROOT_VALUE_SEPARATOR) {
1332 gen.setRootValueSeparator(rootSep);
1333 }
Tatu Salorantaf15531c2011-12-22 23:00:40 -08001334 return gen;
1335 }
1336
1337 protected Writer _createWriter(OutputStream out, JsonEncoding enc, IOContext ctxt) throws IOException
1338 {
1339 // note: this should not get called any more (caller checks, dispatches)
1340 if (enc == JsonEncoding.UTF8) { // We have optimized writer for UTF-8
1341 return new UTF8Writer(ctxt, out);
1342 }
1343 // not optimal, but should do unless we really care about UTF-16/32 encoding speed
1344 return new OutputStreamWriter(out, enc.getJavaName());
1345 }
1346
1347 /*
1348 /**********************************************************
1349 /* Internal factory methods, other
1350 /**********************************************************
1351 */
1352
1353 /**
1354 * Overridable factory method that actually instantiates desired
1355 * context object.
1356 */
1357 protected IOContext _createContext(Object srcRef, boolean resourceManaged)
1358 {
1359 return new IOContext(_getBufferRecycler(), srcRef, resourceManaged);
1360 }
1361
1362 /**
1363 * Method used by factory to create buffer recycler instances
1364 * for parsers and generators.
1365 *<p>
1366 * Note: only public to give access for <code>ObjectMapper</code>
1367 */
1368 public BufferRecycler _getBufferRecycler()
1369 {
1370 SoftReference<BufferRecycler> ref = _recyclerRef.get();
1371 BufferRecycler br = (ref == null) ? null : ref.get();
1372
1373 if (br == null) {
1374 br = new BufferRecycler();
1375 _recyclerRef.set(new SoftReference<BufferRecycler>(br));
1376 }
1377 return br;
1378 }
1379
1380 /**
1381 * Helper methods used for constructing an optimal stream for
1382 * parsers to use, when input is to be read from an URL.
1383 * This helps when reading file content via URL.
1384 */
1385 protected InputStream _optimizedStreamFromURL(URL url)
1386 throws IOException
1387 {
1388 if ("file".equals(url.getProtocol())) {
1389 /* Can not do this if the path refers
1390 * to a network drive on windows. This fixes the problem;
1391 * might not be needed on all platforms (NFS?), but should not
1392 * matter a lot: performance penalty of extra wrapping is more
1393 * relevant when accessing local file system.
1394 */
1395 String host = url.getHost();
1396 if (host == null || host.length() == 0) {
1397 return new FileInputStream(url.getPath());
1398 }
1399 }
1400 return url.openStream();
1401 }
1402}