blob: 3a76f35d4399bb5bde9877bd878d8a2324415b57 [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 */
50public class JsonFactory implements Versioned
51{
52 /**
53 * Name used to identify JSON format
54 * (and returned by {@link #getFormatName()}
55 */
56 public final static String FORMAT_NAME_JSON = "JSON";
57
58 /**
Tatu07351902012-01-19 13:12:13 -080059 * Bitfield (set of flags) of all factory features that are enabled by default.
60 */
61 protected final static int DEFAULT_FACTORY_FEATURE_FLAGS = JsonFactory.Feature.collectDefaults();
62
63 /**
Tatu Salorantaf15531c2011-12-22 23:00:40 -080064 * Bitfield (set of flags) of all parser features that are enabled
65 * by default.
66 */
Tatu07351902012-01-19 13:12:13 -080067 protected final static int DEFAULT_PARSER_FEATURE_FLAGS = JsonParser.Feature.collectDefaults();
68
Tatu Salorantaf15531c2011-12-22 23:00:40 -080069 /**
70 * Bitfield (set of flags) of all generator features that are enabled
71 * by default.
72 */
Tatu07351902012-01-19 13:12:13 -080073 protected final static int DEFAULT_GENERATOR_FEATURE_FLAGS = JsonGenerator.Feature.collectDefaults();
Tatu Salorantaf15531c2011-12-22 23:00:40 -080074
Tatu Salorantae6dfc692012-09-28 15:34:05 -070075 private final static SerializableString DEFAULT_ROOT_VALUE_SEPARATOR = DefaultPrettyPrinter.DEFAULT_ROOT_VALUE_SEPARATOR;
76
Tatu07351902012-01-19 13:12:13 -080077 /**
78 * Enumeration that defines all on/off features that can only be
79 * changed for {@link JsonFactory}.
80 */
81 public enum Feature {
82
83 // // // Symbol handling (interning etc)
84
85 /**
86 * Feature that determines whether JSON object field names are
87 * to be canonicalized using {@link String#intern} or not:
88 * if enabled, all field names will be intern()ed (and caller
89 * can count on this being true for all such names); if disabled,
90 * no intern()ing is done. There may still be basic
91 * canonicalization (that is, same String will be used to represent
92 * all identical object property names for a single document).
93 *<p>
94 * Note: this setting only has effect if
95 * {@link #CANONICALIZE_FIELD_NAMES} is true -- otherwise no
96 * canonicalization of any sort is done.
97 *<p>
98 * This setting is enabled by default.
99 */
100 INTERN_FIELD_NAMES(true),
101
102 /**
103 * Feature that determines whether JSON object field names are
104 * to be canonicalized (details of how canonicalization is done
105 * then further specified by
106 * {@link #INTERN_FIELD_NAMES}).
107 *<p>
108 * This setting is enabled by default.
109 */
110 CANONICALIZE_FIELD_NAMES(true)
111
112 ;
113
114 /**
115 * Whether feature is enabled or disabled by default.
116 */
117 private final boolean _defaultState;
118
119 /**
120 * Method that calculates bit set (flags) of all features that
121 * are enabled by default.
122 */
123 public static int collectDefaults()
124 {
125 int flags = 0;
126 for (Feature f : values()) {
127 if (f.enabledByDefault()) {
128 flags |= f.getMask();
129 }
130 }
131 return flags;
132 }
133
134 private Feature(boolean defaultState)
135 {
136 _defaultState = defaultState;
137 }
138
139 public boolean enabledByDefault() { return _defaultState; }
140
141 public boolean enabledIn(int flags) { return (flags & getMask()) != 0; }
142
143 public int getMask() { return (1 << ordinal()); }
144 }
Tatu Salorantaf15531c2011-12-22 23:00:40 -0800145 /*
146 /**********************************************************
147 /* Buffer, symbol table management
148 /**********************************************************
149 */
150
151 /**
Tatu Saloranta10c3ec82012-09-05 19:38:49 -0700152 * This <code>ThreadLocal</code> contains a {@link java.lang.ref.SoftReference}
Tatu Salorantaf15531c2011-12-22 23:00:40 -0800153 * to a {@link BufferRecycler} used to provide a low-cost
154 * buffer recycling between reader and writer instances.
155 */
156 final protected static ThreadLocal<SoftReference<BufferRecycler>> _recyclerRef
157 = new ThreadLocal<SoftReference<BufferRecycler>>();
158
159 /**
160 * Each factory comes equipped with a shared root symbol table.
161 * It should not be linked back to the original blueprint, to
162 * avoid contents from leaking between factories.
163 */
164 protected CharsToNameCanonicalizer _rootCharSymbols = CharsToNameCanonicalizer.createRoot();
165
166 /**
167 * Alternative to the basic symbol table, some stream-based
168 * parsers use different name canonicalization method.
169 *<p>
170 * TODO: should clean up this; looks messy having 2 alternatives
171 * with not very clear differences.
172 */
173 protected BytesToNameCanonicalizer _rootByteSymbols = BytesToNameCanonicalizer.createRoot();
174
175 /*
176 /**********************************************************
177 /* Configuration
178 /**********************************************************
179 */
180
181 /**
182 * Object that implements conversion functionality between
183 * Java objects and JSON content. For base JsonFactory implementation
184 * usually not set by default, but can be explicitly set.
185 * Sub-classes (like @link org.codehaus.jackson.map.MappingJsonFactory}
186 * usually provide an implementation.
187 */
188 protected ObjectCodec _objectCodec;
189
190 /**
Tatu07351902012-01-19 13:12:13 -0800191 * Currently enabled factory features.
192 */
193 protected int _factoryFeatures = DEFAULT_FACTORY_FEATURE_FLAGS;
194
195 /**
Tatu Salorantaf15531c2011-12-22 23:00:40 -0800196 * Currently enabled parser features.
197 */
198 protected int _parserFeatures = DEFAULT_PARSER_FEATURE_FLAGS;
199
200 /**
201 * Currently enabled generator features.
202 */
203 protected int _generatorFeatures = DEFAULT_GENERATOR_FEATURE_FLAGS;
204
205 /**
206 * Definition of custom character escapes to use for generators created
207 * by this factory, if any. If null, standard data format specific
208 * escapes are used.
209 */
210 protected CharacterEscapes _characterEscapes;
211
212 /**
213 * Optional helper object that may decorate input sources, to do
214 * additional processing on input during parsing.
215 */
216 protected InputDecorator _inputDecorator;
217
218 /**
219 * Optional helper object that may decorate output object, to do
220 * additional processing on output during content generation.
221 */
222 protected OutputDecorator _outputDecorator;
Tatu Salorantae6dfc692012-09-28 15:34:05 -0700223
224 /**
225 * Separator used between root-level values, if any; null indicates
226 * "do not add separator".
227 * Default separator is a single space character.
228 *
229 * @since 2.1
230 */
231 protected SerializableString _rootValueSeparator = DEFAULT_ROOT_VALUE_SEPARATOR;
Tatu Salorantaf15531c2011-12-22 23:00:40 -0800232
233 /*
234 /**********************************************************
235 /* Construction
236 /**********************************************************
237 */
238
239 /**
240 * Default constructor used to create factory instances.
241 * Creation of a factory instance is a light-weight operation,
242 * but it is still a good idea to reuse limited number of
243 * factory instances (and quite often just a single instance):
244 * factories are used as context for storing some reused
245 * processing objects (such as symbol tables parsers use)
246 * and this reuse only works within context of a single
247 * factory instance.
248 */
249 public JsonFactory() { this(null); }
250
251 public JsonFactory(ObjectCodec oc) { _objectCodec = oc; }
252
Tatu Saloranta378ecdc2012-08-04 16:27:27 -0700253 /**
254 * Method for constructing a new {@link JsonFactory} that has
255 * the same settings as this instance, but is otherwise
256 * independent (i.e. nothing is actually shared, symbol tables
257 * are separate).
258 * Note that {@link ObjectCodec} reference is not copied but is
259 * set to null; caller typically needs to set it after calling
260 * this method.
261 *
262 * @since 2.1
263 */
264 public JsonFactory copy()
265 {
266 _checkInvalidCopy(JsonFactory.class);
267 return new JsonFactory(null);
268 }
269
270 /**
271 * @since 2.1
272 * @param exp
273 */
274 protected void _checkInvalidCopy(Class<?> exp)
275 {
276 if (getClass() != exp) {
277 throw new IllegalStateException("Failed copy(): "+getClass().getName()
278 +" (version: "+version()+") does not override copy(); it has to");
279 }
280 }
281
Tatu Salorantaf15531c2011-12-22 23:00:40 -0800282 /*
283 /**********************************************************
284 /* Format detection functionality (since 1.8)
285 /**********************************************************
286 */
287
288 /**
Tatu Saloranta1bdf0262012-08-24 14:43:17 -0700289 * Method that can be used to quickly check whether given schema
290 * is something that parsers and/or generators constructed by this
291 * factory could use. Note that this means possible use, at the level
292 * of data format (i.e. schema is for same data format as parsers and
293 * generators this factory constructs); individual schema instances
294 * may have further usage restrictions.
295 *
296 * @since 2.1
297 */
298 public boolean canUseSchema(FormatSchema schema) {
299 String ourFormat = getFormatName();
300 return (ourFormat != null) && ourFormat.equals(schema.getSchemaType());
301 }
302
303 /**
Tatu Salorantaf15531c2011-12-22 23:00:40 -0800304 * Method that returns short textual id identifying format
305 * this factory supports.
306 *<p>
307 * Note: sub-classes should override this method; default
308 * implementation will return null for all sub-classes
309 */
310 public String getFormatName()
311 {
312 /* Somewhat nasty check: since we can't make this abstract
313 * (due to backwards compatibility concerns), need to prevent
314 * format name "leakage"
315 */
316 if (getClass() == JsonFactory.class) {
317 return FORMAT_NAME_JSON;
318 }
319 return null;
320 }
321
322 public MatchStrength hasFormat(InputAccessor acc) throws IOException
323 {
324 // since we can't keep this abstract, only implement for "vanilla" instance
325 if (getClass() == JsonFactory.class) {
326 return hasJSONFormat(acc);
327 }
328 return null;
329 }
330
Tatu Salorantaad2df5f2012-08-22 20:55:49 -0700331 /**
332 * Method that can be called to determine if a custom
333 * {@link ObjectCodec} is needed for binding data parsed
334 * using {@link JsonParser} constructed by this factory
335 * (which typically also implies the same for serialization
336 * with {@link JsonGenerator}).
337 *
338 * @return True if custom codec is needed with parsers and
339 * generators created by this factory; false if a general
340 * {@link ObjectCodec} is enough
341 *
342 * @since 2.1
343 */
344 public boolean requiresCustomCodec() {
345 return false;
346 }
347
348 /**
349 * Helper method that can be called to determine if content accessed
350 * using given accessor seems to be JSON content.
351 */
Tatu Salorantaf15531c2011-12-22 23:00:40 -0800352 protected MatchStrength hasJSONFormat(InputAccessor acc) throws IOException
353 {
354 return ByteSourceJsonBootstrapper.hasJSONFormat(acc);
Tatu Salorantaad2df5f2012-08-22 20:55:49 -0700355 }
356
Tatu Salorantaf15531c2011-12-22 23:00:40 -0800357 /*
358 /**********************************************************
359 /* Versioned
360 /**********************************************************
361 */
362
Tatu Salorantae9b48512012-04-17 10:22:07 -0700363// @Override
Tatu Salorantaf15531c2011-12-22 23:00:40 -0800364 public Version version() {
Tatu Saloranta5a1bd992011-12-28 23:18:23 -0800365 return CoreVersion.instance.version();
Tatu Salorantaf15531c2011-12-22 23:00:40 -0800366 }
367
368 /*
369 /**********************************************************
Tatu07351902012-01-19 13:12:13 -0800370 /* Configuration, factory features
Tatu Salorantaf15531c2011-12-22 23:00:40 -0800371 /**********************************************************
372 */
373
374 /**
375 * Method for enabling or disabling specified parser feature
376 * (check {@link JsonParser.Feature} for list of features)
377 */
Tatu07351902012-01-19 13:12:13 -0800378 public final JsonFactory configure(JsonFactory.Feature f, boolean state) {
379 return state ? enable(f) : disable(f);
380 }
381
382 /**
383 * Method for enabling specified parser feature
384 * (check {@link JsonFactory.Feature} for list of features)
385 */
386 public JsonFactory enable(JsonFactory.Feature f) {
387 _factoryFeatures |= f.getMask();
Tatu Salorantaf15531c2011-12-22 23:00:40 -0800388 return this;
389 }
390
391 /**
Tatu07351902012-01-19 13:12:13 -0800392 * Method for disabling specified parser features
393 * (check {@link JsonFactory.Feature} for list of features)
394 */
395 public JsonFactory disable(JsonFactory.Feature f) {
396 _factoryFeatures &= ~f.getMask();
397 return this;
398 }
399
400 /**
401 * Checked whether specified parser feature is enabled.
402 */
403 public final boolean isEnabled(JsonFactory.Feature f) {
404 return (_factoryFeatures & f.getMask()) != 0;
405 }
406
407 /*
408 /**********************************************************
409 /* Configuration, parser configuration
410 /**********************************************************
411 */
412
413 /**
414 * Method for enabling or disabling specified parser feature
415 * (check {@link JsonParser.Feature} for list of features)
416 */
417 public final JsonFactory configure(JsonParser.Feature f, boolean state) {
418 return state ? enable(f) : disable(f);
419 }
420
421 /**
Tatu Salorantaf15531c2011-12-22 23:00:40 -0800422 * Method for enabling specified parser feature
423 * (check {@link JsonParser.Feature} for list of features)
424 */
425 public JsonFactory enable(JsonParser.Feature f) {
426 _parserFeatures |= f.getMask();
427 return this;
428 }
429
430 /**
431 * Method for disabling specified parser features
432 * (check {@link JsonParser.Feature} for list of features)
433 */
434 public JsonFactory disable(JsonParser.Feature f) {
435 _parserFeatures &= ~f.getMask();
436 return this;
437 }
438
439 /**
440 * Checked whether specified parser feature is enabled.
441 */
442 public final boolean isEnabled(JsonParser.Feature f) {
443 return (_parserFeatures & f.getMask()) != 0;
444 }
445
446 /**
447 * Method for getting currently configured input decorator (if any;
448 * there is no default decorator).
449 */
450 public InputDecorator getInputDecorator() {
451 return _inputDecorator;
452 }
453
454 /**
455 * Method for overriding currently configured input decorator
456 */
457 public JsonFactory setInputDecorator(InputDecorator d) {
458 _inputDecorator = d;
459 return this;
460 }
461
462 /*
463 /**********************************************************
464 /* Configuration, generator settings
465 /**********************************************************
466 */
467
468 /**
469 * Method for enabling or disabling specified generator feature
470 * (check {@link JsonGenerator.Feature} for list of features)
471 */
472 public final JsonFactory configure(JsonGenerator.Feature f, boolean state) {
Tatu07351902012-01-19 13:12:13 -0800473 return state ? enable(f) : disable(f);
Tatu Salorantaf15531c2011-12-22 23:00:40 -0800474 }
475
476
477 /**
478 * Method for enabling specified generator features
479 * (check {@link JsonGenerator.Feature} for list of features)
480 */
481 public JsonFactory enable(JsonGenerator.Feature f) {
482 _generatorFeatures |= f.getMask();
483 return this;
484 }
485
486 /**
487 * Method for disabling specified generator feature
488 * (check {@link JsonGenerator.Feature} for list of features)
489 */
490 public JsonFactory disable(JsonGenerator.Feature f) {
491 _generatorFeatures &= ~f.getMask();
492 return this;
493 }
494
495 /**
496 * Check whether specified generator feature is enabled.
497 */
498 public final boolean isEnabled(JsonGenerator.Feature f) {
499 return (_generatorFeatures & f.getMask()) != 0;
500 }
501
502 /**
503 * Method for accessing custom escapes factory uses for {@link JsonGenerator}s
504 * it creates.
505 */
506 public CharacterEscapes getCharacterEscapes() {
507 return _characterEscapes;
508 }
509
510 /**
511 * Method for defining custom escapes factory uses for {@link JsonGenerator}s
512 * it creates.
513 */
514 public JsonFactory setCharacterEscapes(CharacterEscapes esc) {
515 _characterEscapes = esc;
516 return this;
517 }
518
519 /**
520 * Method for getting currently configured output decorator (if any;
521 * there is no default decorator).
522 */
523 public OutputDecorator getOutputDecorator() {
524 return _outputDecorator;
525 }
526
527 /**
528 * Method for overriding currently configured output decorator
529 */
530 public JsonFactory setOutputDecorator(OutputDecorator d) {
531 _outputDecorator = d;
532 return this;
533 }
Tatu Salorantae6dfc692012-09-28 15:34:05 -0700534
535 /**
536 * Method that allows overriding String used for separating root-level
537 * JSON values (default is single space character)
538 *
539 * @param sep Separator to use, if any; null means that no separator is
540 * automatically added
541 *
542 * @since 2.1
543 */
544 public JsonFactory setRootValueSeparator(String sep) {
545 _rootValueSeparator = (sep == null) ? null : new SerializedString(sep);
546 return this;
547 }
548
549 /**
550 * @since 2.1
551 */
552 public String getRootValueSeparator() {
553 return (_rootValueSeparator == null) ? null : _rootValueSeparator.getValue();
554 }
Tatu Salorantaf15531c2011-12-22 23:00:40 -0800555
556 /*
557 /**********************************************************
558 /* Configuration, other
559 /**********************************************************
560 */
561
562 /**
563 * Method for associating a {@link ObjectCodec} (typically
Tatu Salorantad77350e2011-12-22 23:13:13 -0800564 * a <code>com.fasterxml.jackson.databind.ObjectMapper</code>)
565 * with this factory (and more importantly, parsers and generators
Tatu Salorantaf15531c2011-12-22 23:00:40 -0800566 * it constructs). This is needed to use data-binding methods
567 * of {@link JsonParser} and {@link JsonGenerator} instances.
568 */
569 public JsonFactory setCodec(ObjectCodec oc) {
570 _objectCodec = oc;
571 return this;
572 }
573
574 public ObjectCodec getCodec() { return _objectCodec; }
575
576 /*
577 /**********************************************************
Tatu Salorantafeaabd12012-07-22 23:03:41 -0700578 /* Parser factories (new ones, as per [Issue-25])
Tatu Salorantaf15531c2011-12-22 23:00:40 -0800579 /**********************************************************
580 */
581
582 /**
583 * Method for constructing JSON parser instance to parse
584 * contents of specified file. Encoding is auto-detected
585 * from contents according to JSON specification recommended
586 * mechanism.
587 *<p>
588 * Underlying input stream (needed for reading contents)
589 * will be <b>owned</b> (and managed, i.e. closed as need be) by
590 * the parser, since caller has no access to it.
591 *
592 * @param f File that contains JSON content to parse
Tatu Salorantafeaabd12012-07-22 23:03:41 -0700593 *
594 * @since 2.1
595 */
596 public JsonParser createParser(File f)
597 throws IOException, JsonParseException
598 {
599 // Must delegate to old version, until 2.2
600 // TODO: change direction in 2.2; after ensuring impls support new method
601 return createJsonParser(f);
602 }
603
604 /**
605 * Method for constructing JSON parser instance to parse
606 * contents of resource reference by given URL.
607 * Encoding is auto-detected
608 * from contents according to JSON specification recommended
609 * mechanism.
610 *<p>
611 * Underlying input stream (needed for reading contents)
612 * will be <b>owned</b> (and managed, i.e. closed as need be) by
613 * the parser, since caller has no access to it.
614 *
615 * @param url URL pointing to resource that contains JSON content to parse
616 *
617 * @since 2.1
618 */
619 public JsonParser createParser(URL url)
620 throws IOException, JsonParseException
621 {
622 // Must delegate to old version, until 2.2
623 // TODO: change direction in 2.2; after ensuring impls support new method
624 return createJsonParser(url);
625 }
626
627 /**
628 * Method for constructing JSON parser instance to parse
629 * the contents accessed via specified input stream.
630 *<p>
631 * The input stream will <b>not be owned</b> by
632 * the parser, it will still be managed (i.e. closed if
633 * end-of-stream is reacher, or parser close method called)
634 * if (and only if) {@link com.fasterxml.jackson.core.JsonParser.Feature#AUTO_CLOSE_SOURCE}
635 * is enabled.
636 *<p>
637 * Note: no encoding argument is taken since it can always be
638 * auto-detected as suggested by JSON RFC.
639 *
640 * @param in InputStream to use for reading JSON content to parse
641 *
642 * @since 2.1
643 */
644 public JsonParser createParser(InputStream in)
645 throws IOException, JsonParseException
646 {
647 // Must delegate to old version, until 2.2
648 // TODO: change direction in 2.2; after ensuring impls support new method
649 return createJsonParser(in);
650 }
651
652 /**
653 * Method for constructing parser for parsing
654 * the contents accessed via specified Reader.
655 <p>
656 * The read stream will <b>not be owned</b> by
657 * the parser, it will still be managed (i.e. closed if
658 * end-of-stream is reacher, or parser close method called)
659 * if (and only if) {@link com.fasterxml.jackson.core.JsonParser.Feature#AUTO_CLOSE_SOURCE}
660 * is enabled.
661 *
662 * @param r Reader to use for reading JSON content to parse
663 *
664 * @since 2.1
665 */
666 public JsonParser createParser(Reader r)
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(r);
672 }
673
674 /**
675 * Method for constructing parser for parsing
676 * the contents of given byte array.
677 *
678 * @since 2.1
679 */
680 public JsonParser createParser(byte[] data)
681 throws IOException, JsonParseException
682 {
683 // Must delegate to old version, until 2.2
684 // TODO: change direction in 2.2; after ensuring impls support new method
685 return createJsonParser(data);
686 }
687
688 /**
689 * Method for constructing parser for parsing
690 * the contents of given byte array.
691 *
692 * @param data Buffer that contains data to parse
693 * @param offset Offset of the first data byte within buffer
694 * @param len Length of contents to parse within buffer
695 *
696 * @since 2.1
697 */
698 public JsonParser createParser(byte[] data, int offset, int len)
699 throws IOException, JsonParseException
700 {
701 // Must delegate to old version, until 2.2
702 // TODO: change direction in 2.2; after ensuring impls support new method
703 return createJsonParser(data, offset, len);
704 }
705
706 /**
707 * Method for constructing parser for parsing
708 * contents of given String.
709 *
710 * @since 2.1
711 */
712 public JsonParser createParser(String content)
713 throws IOException, JsonParseException
714 {
715 // Must delegate to old version, until 2.2
716 // TODO: change direction in 2.2; after ensuring impls support new method
717 return createJsonParser(content);
718 }
719
720 /*
721 /**********************************************************
722 /* Parser factories (old ones, as per [Issue-25])
723 /**********************************************************
724 */
725
726 /**
727 * Method for constructing JSON parser instance to parse
728 * contents of specified file. Encoding is auto-detected
729 * from contents according to JSON specification recommended
730 * mechanism.
731 *<p>
732 * Underlying input stream (needed for reading contents)
733 * will be <b>owned</b> (and managed, i.e. closed as need be) by
734 * the parser, since caller has no access to it.
735 *<p>
736 * NOTE: as of 2.1, should not be used (will be deprecated in 2.2);
737 * instead, should call <code>createParser</code>.
738 *
739 * @param f File that contains JSON content to parse
Tatu Salorantaf15531c2011-12-22 23:00:40 -0800740 */
741 public JsonParser createJsonParser(File f)
742 throws IOException, JsonParseException
743 {
744 // true, since we create InputStream from File
745 IOContext ctxt = _createContext(f, true);
746 InputStream in = new FileInputStream(f);
747 // [JACKSON-512]: allow wrapping with InputDecorator
748 if (_inputDecorator != null) {
749 in = _inputDecorator.decorate(ctxt, in);
750 }
Tatu Salorantaeeb2fbd2012-05-28 22:00:08 -0700751 return _createParser(in, ctxt);
Tatu Salorantaf15531c2011-12-22 23:00:40 -0800752 }
753
754 /**
755 * Method for constructing JSON parser instance to parse
756 * contents of resource reference by given URL.
757 * Encoding is auto-detected
758 * from contents according to JSON specification recommended
759 * mechanism.
760 *<p>
761 * Underlying input stream (needed for reading contents)
762 * will be <b>owned</b> (and managed, i.e. closed as need be) by
763 * the parser, since caller has no access to it.
Tatu Salorantafeaabd12012-07-22 23:03:41 -0700764 *<p>
765 * NOTE: as of 2.1, should not be used (will be deprecated in 2.2);
766 * instead, should call <code>createParser</code>.
Tatu Salorantaf15531c2011-12-22 23:00:40 -0800767 *
768 * @param url URL pointing to resource that contains JSON content to parse
769 */
770 public JsonParser createJsonParser(URL url)
771 throws IOException, JsonParseException
772 {
773 // true, since we create InputStream from URL
774 IOContext ctxt = _createContext(url, true);
775 InputStream in = _optimizedStreamFromURL(url);
776 // [JACKSON-512]: allow wrapping with InputDecorator
777 if (_inputDecorator != null) {
778 in = _inputDecorator.decorate(ctxt, in);
779 }
Tatu Salorantaeeb2fbd2012-05-28 22:00:08 -0700780 return _createParser(in, ctxt);
Tatu Salorantaf15531c2011-12-22 23:00:40 -0800781 }
782
783 /**
784 * Method for constructing JSON parser instance to parse
785 * the contents accessed via specified input stream.
786 *<p>
787 * The input stream will <b>not be owned</b> by
788 * the parser, it will still be managed (i.e. closed if
789 * end-of-stream is reacher, or parser close method called)
790 * if (and only if) {@link com.fasterxml.jackson.core.JsonParser.Feature#AUTO_CLOSE_SOURCE}
791 * is enabled.
792 *<p>
793 * Note: no encoding argument is taken since it can always be
Tatu Salorantafeaabd12012-07-22 23:03:41 -0700794 * auto-detected as suggested by JSON RFC.
795 *<p>
796 * NOTE: as of 2.1, should not be used (will be deprecated in 2.2);
797 * instead, should call <code>createParser</code>.
Tatu Salorantaf15531c2011-12-22 23:00:40 -0800798 *
799 * @param in InputStream to use for reading JSON content to parse
800 */
801 public JsonParser createJsonParser(InputStream in)
802 throws IOException, JsonParseException
803 {
804 IOContext ctxt = _createContext(in, false);
805 // [JACKSON-512]: allow wrapping with InputDecorator
806 if (_inputDecorator != null) {
807 in = _inputDecorator.decorate(ctxt, in);
808 }
Tatu Salorantaeeb2fbd2012-05-28 22:00:08 -0700809 return _createParser(in, ctxt);
Tatu Salorantaf15531c2011-12-22 23:00:40 -0800810 }
811
812 /**
813 * Method for constructing parser for parsing
814 * the contents accessed via specified Reader.
815 <p>
816 * The read stream will <b>not be owned</b> by
817 * the parser, it will still be managed (i.e. closed if
818 * end-of-stream is reacher, or parser close method called)
819 * if (and only if) {@link com.fasterxml.jackson.core.JsonParser.Feature#AUTO_CLOSE_SOURCE}
820 * is enabled.
821 *<p>
Tatu Salorantafeaabd12012-07-22 23:03:41 -0700822 * NOTE: as of 2.1, should not be used (will be deprecated in 2.2);
823 * instead, should call <code>createParser</code>.
Tatu Salorantaf15531c2011-12-22 23:00:40 -0800824 *
825 * @param r Reader to use for reading JSON content to parse
826 */
827 public JsonParser createJsonParser(Reader r)
828 throws IOException, JsonParseException
829 {
830 // false -> we do NOT own Reader (did not create it)
831 IOContext ctxt = _createContext(r, false);
832 // [JACKSON-512]: allow wrapping with InputDecorator
833 if (_inputDecorator != null) {
834 r = _inputDecorator.decorate(ctxt, r);
835 }
Tatu Saloranta3e5ff6d2012-06-27 18:46:43 -0700836 return _createParser(r, ctxt);
Tatu Salorantaf15531c2011-12-22 23:00:40 -0800837 }
838
839 /**
840 * Method for constructing parser for parsing
841 * the contents of given byte array.
Tatu Salorantafeaabd12012-07-22 23:03:41 -0700842 *<p>
843 * NOTE: as of 2.1, should not be used (will be deprecated in 2.2);
844 * instead, should call <code>createParser</code>.
Tatu Salorantaf15531c2011-12-22 23:00:40 -0800845 */
846 public JsonParser createJsonParser(byte[] data)
847 throws IOException, JsonParseException
848 {
849 IOContext ctxt = _createContext(data, true);
850 // [JACKSON-512]: allow wrapping with InputDecorator
851 if (_inputDecorator != null) {
852 InputStream in = _inputDecorator.decorate(ctxt, data, 0, data.length);
853 if (in != null) {
Tatu Salorantaeeb2fbd2012-05-28 22:00:08 -0700854 return _createParser(in, ctxt);
Tatu Salorantaf15531c2011-12-22 23:00:40 -0800855 }
856 }
Tatu Salorantaeeb2fbd2012-05-28 22:00:08 -0700857 return _createParser(data, 0, data.length, ctxt);
Tatu Salorantaf15531c2011-12-22 23:00:40 -0800858 }
859
860 /**
861 * Method for constructing parser for parsing
862 * the contents of given byte array.
Tatu Salorantafeaabd12012-07-22 23:03:41 -0700863 *<p>
864 * NOTE: as of 2.1, should not be used (will be deprecated in 2.2);
865 * instead, should call <code>createParser</code>.
Tatu Salorantaf15531c2011-12-22 23:00:40 -0800866 *
867 * @param data Buffer that contains data to parse
868 * @param offset Offset of the first data byte within buffer
869 * @param len Length of contents to parse within buffer
870 */
871 public JsonParser createJsonParser(byte[] data, int offset, int len)
872 throws IOException, JsonParseException
873 {
874 IOContext ctxt = _createContext(data, true);
875 // [JACKSON-512]: allow wrapping with InputDecorator
876 if (_inputDecorator != null) {
877 InputStream in = _inputDecorator.decorate(ctxt, data, offset, len);
878 if (in != null) {
Tatu Salorantaeeb2fbd2012-05-28 22:00:08 -0700879 return _createParser(in, ctxt);
Tatu Salorantaf15531c2011-12-22 23:00:40 -0800880 }
881 }
Tatu Salorantaeeb2fbd2012-05-28 22:00:08 -0700882 return _createParser(data, offset, len, ctxt);
Tatu Salorantaf15531c2011-12-22 23:00:40 -0800883 }
884
885 /**
886 * Method for constructing parser for parsing
887 * contents of given String.
Tatu Salorantafeaabd12012-07-22 23:03:41 -0700888 *<p>
889 * NOTE: as of 2.1, should not be used (will be deprecated in 2.2);
890 * instead, should call <code>createParser</code>.
Tatu Salorantaf15531c2011-12-22 23:00:40 -0800891 */
892 public JsonParser createJsonParser(String content)
893 throws IOException, JsonParseException
894 {
Tatu Saloranta3e5ff6d2012-06-27 18:46:43 -0700895 Reader r = new StringReader(content);
Tatu Salorantaf15531c2011-12-22 23:00:40 -0800896 // true -> we own the Reader (and must close); not a big deal
897 IOContext ctxt = _createContext(r, true);
898 // [JACKSON-512]: allow wrapping with InputDecorator
899 if (_inputDecorator != null) {
900 r = _inputDecorator.decorate(ctxt, r);
901 }
Tatu Saloranta3e5ff6d2012-06-27 18:46:43 -0700902 return _createParser(r, ctxt);
Tatu Salorantaf15531c2011-12-22 23:00:40 -0800903 }
904
905 /*
906 /**********************************************************
Tatu Salorantafeaabd12012-07-22 23:03:41 -0700907 /* Generator factories, new (as per [Issue-25]
Tatu Salorantaf15531c2011-12-22 23:00:40 -0800908 /**********************************************************
909 */
910
911 /**
912 * Method for constructing JSON generator for writing JSON content
913 * using specified output stream.
914 * Encoding to use must be specified, and needs to be one of available
915 * types (as per JSON specification).
916 *<p>
917 * Underlying stream <b>is NOT owned</b> by the generator constructed,
918 * so that generator will NOT close the output stream when
919 * {@link JsonGenerator#close} is called (unless auto-closing
920 * feature,
921 * {@link com.fasterxml.jackson.core.JsonGenerator.Feature#AUTO_CLOSE_TARGET}
922 * is enabled).
923 * Using application needs to close it explicitly if this is the case.
924 *<p>
925 * Note: there are formats that use fixed encoding (like most binary data formats)
926 * and that ignore passed in encoding.
Tatu Salorantafeaabd12012-07-22 23:03:41 -0700927 *<p>
928 * NOTE: starting with 2.1, should not be used (will be deprecated in 2.2);
929 * instead, should call <code>createGenerator</code>.
930 *
931 * @since 2.1 Will eventually replace <code>createJsonGenerator</code> variant.
932 *
933 * @param out OutputStream to use for writing JSON content
934 * @param enc Character encoding to use
935 */
936 public JsonGenerator createGenerator(OutputStream out, JsonEncoding enc)
937 throws IOException
938 {
939 return createJsonGenerator(out, enc);
940 }
941
942 /**
943 * Method for constructing JSON generator for writing JSON content
944 * using specified Writer.
945 *<p>
946 * Underlying stream <b>is NOT owned</b> by the generator constructed,
947 * so that generator will NOT close the Reader when
948 * {@link JsonGenerator#close} is called (unless auto-closing
949 * feature,
950 * {@link com.fasterxml.jackson.core.JsonGenerator.Feature#AUTO_CLOSE_TARGET} is enabled).
951 * Using application needs to close it explicitly.
952 *<p>
953 * NOTE: starting with 2.1, should not be used (will be deprecated in 2.2);
954 * instead, should call <code>createGenerator</code>.
955 *
956 * @since 2.1 Will eventually replace <code>createJsonGenerator</code> variant.
957 *
958 * @param out Writer to use for writing JSON content
959 */
960 public JsonGenerator createGenerator(Writer out)
961 throws IOException
962 {
963 return createJsonGenerator(out);
964 }
965
966 /**
967 * Convenience method for constructing generator that uses default
968 * encoding of the format (UTF-8 for JSON and most other data formats).
969 *<p>
970 * Note: there are formats that use fixed encoding (like most binary data formats).
971 *<p>
972 * NOTE: starting with 2.1, should not be used (will be deprecated in 2.2);
973 * instead, should call <code>createGenerator</code>.
974 *
975 * @since 2.1 Will eventually replace <code>createJsonGenerator</code> variant.
976 */
977 public JsonGenerator createGenerator(OutputStream out) throws IOException {
978 return createJsonGenerator(out);
979 }
980
981 /**
982 * Method for constructing JSON generator for writing JSON content
983 * to specified file, overwriting contents it might have (or creating
984 * it if such file does not yet exist).
985 * Encoding to use must be specified, and needs to be one of available
986 * types (as per JSON specification).
987 *<p>
988 * Underlying stream <b>is owned</b> by the generator constructed,
989 * i.e. generator will handle closing of file when
990 * {@link JsonGenerator#close} is called.
991 *<p>
992 * NOTE: starting with 2.1, should not be used (will be deprecated in 2.2);
993 * instead, should call <code>createGenerator</code>.
994 *
995 * @since 2.1 Will eventually replace <code>createJsonGenerator</code> variant.
996 *
997 * @param f File to write contents to
998 * @param enc Character encoding to use
999 */
1000 public JsonGenerator createGenerator(File f, JsonEncoding enc)
1001 throws IOException
1002 {
1003 return createJsonGenerator(f, enc);
1004 }
1005
1006 /*
1007 /**********************************************************
1008 /* Generator factories, old (as per [Issue-25]
1009 /**********************************************************
1010 */
1011
1012 /**
1013 * Method for constructing JSON generator for writing JSON content
1014 * using specified output stream.
1015 * Encoding to use must be specified, and needs to be one of available
1016 * types (as per JSON specification).
1017 *<p>
1018 * Underlying stream <b>is NOT owned</b> by the generator constructed,
1019 * so that generator will NOT close the output stream when
1020 * {@link JsonGenerator#close} is called (unless auto-closing
1021 * feature,
1022 * {@link com.fasterxml.jackson.core.JsonGenerator.Feature#AUTO_CLOSE_TARGET}
1023 * is enabled).
1024 * Using application needs to close it explicitly if this is the case.
1025 *<p>
1026 * Note: there are formats that use fixed encoding (like most binary data formats)
1027 * and that ignore passed in encoding.
1028 *<p>
1029 * NOTE: starting with 2.1, should not be used (will be deprecated in 2.2);
1030 * instead, should call <code>createGenerator</code>.
Tatu Salorantaf15531c2011-12-22 23:00:40 -08001031 *
1032 * @param out OutputStream to use for writing JSON content
1033 * @param enc Character encoding to use
1034 */
1035 public JsonGenerator createJsonGenerator(OutputStream out, JsonEncoding enc)
1036 throws IOException
1037 {
1038 // false -> we won't manage the stream unless explicitly directed to
1039 IOContext ctxt = _createContext(out, false);
1040 ctxt.setEncoding(enc);
1041 if (enc == JsonEncoding.UTF8) {
1042 // [JACKSON-512]: allow wrapping with _outputDecorator
1043 if (_outputDecorator != null) {
1044 out = _outputDecorator.decorate(ctxt, out);
1045 }
1046 return _createUTF8JsonGenerator(out, ctxt);
1047 }
1048 Writer w = _createWriter(out, enc, ctxt);
1049 // [JACKSON-512]: allow wrapping with _outputDecorator
1050 if (_outputDecorator != null) {
1051 w = _outputDecorator.decorate(ctxt, w);
1052 }
Tatu Salorantaeeb2fbd2012-05-28 22:00:08 -07001053 return _createGenerator(w, ctxt);
Tatu Salorantaf15531c2011-12-22 23:00:40 -08001054 }
1055
1056 /**
1057 * Method for constructing JSON generator for writing JSON content
1058 * using specified Writer.
1059 *<p>
1060 * Underlying stream <b>is NOT owned</b> by the generator constructed,
1061 * so that generator will NOT close the Reader when
1062 * {@link JsonGenerator#close} is called (unless auto-closing
1063 * feature,
1064 * {@link com.fasterxml.jackson.core.JsonGenerator.Feature#AUTO_CLOSE_TARGET} is enabled).
1065 * Using application needs to close it explicitly.
Tatu Salorantafeaabd12012-07-22 23:03:41 -07001066 *<p>
1067 * NOTE: starting with 2.1, should not be used (will be deprecated in 2.2);
1068 * instead, should call <code>createGenerator</code>.
Tatu Salorantaf15531c2011-12-22 23:00:40 -08001069 *
1070 * @param out Writer to use for writing JSON content
1071 */
1072 public JsonGenerator createJsonGenerator(Writer out)
1073 throws IOException
1074 {
1075 IOContext ctxt = _createContext(out, false);
1076 // [JACKSON-512]: allow wrapping with _outputDecorator
1077 if (_outputDecorator != null) {
1078 out = _outputDecorator.decorate(ctxt, out);
1079 }
Tatu Salorantaeeb2fbd2012-05-28 22:00:08 -07001080 return _createGenerator(out, ctxt);
Tatu Salorantaf15531c2011-12-22 23:00:40 -08001081 }
1082
1083 /**
1084 * Convenience method for constructing generator that uses default
1085 * encoding of the format (UTF-8 for JSON and most other data formats).
1086 *<p>
1087 * Note: there are formats that use fixed encoding (like most binary data formats).
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 public JsonGenerator createJsonGenerator(OutputStream out) throws IOException {
1093 return createJsonGenerator(out, JsonEncoding.UTF8);
1094 }
1095
1096 /**
1097 * Method for constructing JSON generator for writing JSON content
1098 * to specified file, overwriting contents it might have (or creating
1099 * it if such file does not yet exist).
1100 * Encoding to use must be specified, and needs to be one of available
1101 * types (as per JSON specification).
1102 *<p>
1103 * Underlying stream <b>is owned</b> by the generator constructed,
1104 * i.e. generator will handle closing of file when
1105 * {@link JsonGenerator#close} is called.
Tatu Salorantafeaabd12012-07-22 23:03:41 -07001106 *<p>
1107 * NOTE: starting with 2.1, should not be used (will be deprecated in 2.2);
1108 * instead, should call <code>createGenerator</code>.
Tatu Salorantaf15531c2011-12-22 23:00:40 -08001109 *
1110 * @param f File to write contents to
1111 * @param enc Character encoding to use
1112 */
1113 public JsonGenerator createJsonGenerator(File f, JsonEncoding enc)
1114 throws IOException
1115 {
1116 OutputStream out = new FileOutputStream(f);
1117 // true -> yes, we have to manage the stream since we created it
1118 IOContext ctxt = _createContext(out, true);
1119 ctxt.setEncoding(enc);
1120 if (enc == JsonEncoding.UTF8) {
1121 // [JACKSON-512]: allow wrapping with _outputDecorator
1122 if (_outputDecorator != null) {
1123 out = _outputDecorator.decorate(ctxt, out);
1124 }
1125 return _createUTF8JsonGenerator(out, ctxt);
1126 }
1127 Writer w = _createWriter(out, enc, ctxt);
1128 // [JACKSON-512]: allow wrapping with _outputDecorator
1129 if (_outputDecorator != null) {
1130 w = _outputDecorator.decorate(ctxt, w);
1131 }
Tatu Salorantaeeb2fbd2012-05-28 22:00:08 -07001132 return _createGenerator(w, ctxt);
Tatu Salorantaf15531c2011-12-22 23:00:40 -08001133 }
1134
1135 /*
1136 /**********************************************************
1137 /* Factory methods used by factory for creating parser instances,
1138 /* overridable by sub-classes
1139 /**********************************************************
1140 */
1141
1142 /**
1143 * Overridable factory method that actually instantiates desired parser
1144 * given {@link InputStream} and context object.
1145 *<p>
1146 * This method is specifically designed to remain
1147 * compatible between minor versions so that sub-classes can count
1148 * on it being called as expected. That is, it is part of official
1149 * interface from sub-class perspective, although not a public
1150 * method available to users of factory implementations.
Tatu Salorantaeeb2fbd2012-05-28 22:00:08 -07001151 *
1152 * @since 2.1
Tatu Salorantaf15531c2011-12-22 23:00:40 -08001153 */
Tatu Salorantaeeb2fbd2012-05-28 22:00:08 -07001154 protected JsonParser _createParser(InputStream in, IOContext ctxt)
Tatu Salorantaf15531c2011-12-22 23:00:40 -08001155 throws IOException, JsonParseException
1156 {
Tatu Salorantaeeb2fbd2012-05-28 22:00:08 -07001157 /* NOTE: MUST call the deprecated method until it is deleted, just so
1158 * that override still works as expected, for now.
1159 */
1160 return _createJsonParser(in, ctxt);
1161 }
1162
1163 /**
1164 * @deprecated since 2.1 -- use {@link #_createParser(InputStream, IOContext)} instead
1165 */
1166 @Deprecated
1167 protected JsonParser _createJsonParser(InputStream in, IOContext ctxt) throws IOException, JsonParseException {
Tatu07351902012-01-19 13:12:13 -08001168 // As per [JACKSON-259], may want to fully disable canonicalization:
Tatu Salorantaf15531c2011-12-22 23:00:40 -08001169 return new ByteSourceJsonBootstrapper(ctxt, in).constructParser(_parserFeatures,
Tatu07351902012-01-19 13:12:13 -08001170 _objectCodec, _rootByteSymbols, _rootCharSymbols,
1171 isEnabled(JsonFactory.Feature.CANONICALIZE_FIELD_NAMES),
1172 isEnabled(JsonFactory.Feature.INTERN_FIELD_NAMES));
Tatu Salorantaf15531c2011-12-22 23:00:40 -08001173 }
Tatu Salorantaeeb2fbd2012-05-28 22:00:08 -07001174
Tatu Salorantaf15531c2011-12-22 23:00:40 -08001175 /**
1176 * Overridable factory method that actually instantiates parser
1177 * using given {@link Reader} object for reading content.
1178 *<p>
1179 * This method is specifically designed to remain
1180 * compatible between minor versions so that sub-classes can count
1181 * on it being called as expected. That is, it is part of official
1182 * interface from sub-class perspective, although not a public
1183 * method available to users of factory implementations.
Tatu Salorantaeeb2fbd2012-05-28 22:00:08 -07001184 *
1185 * @since 2.1
Tatu Salorantaf15531c2011-12-22 23:00:40 -08001186 */
Tatu Salorantaeeb2fbd2012-05-28 22:00:08 -07001187 protected JsonParser _createParser(Reader r, IOContext ctxt)
1188 throws IOException, JsonParseException
Tatu Salorantaf15531c2011-12-22 23:00:40 -08001189 {
Tatu Salorantaeeb2fbd2012-05-28 22:00:08 -07001190 /* NOTE: MUST call the deprecated method until it is deleted, just so
1191 * that override still works as expected, for now.
1192 */
1193 return _createJsonParser(r, ctxt);
1194 }
1195
1196 /**
1197 * @deprecated since 2.1 -- use {@link #_createParser(Reader, IOContext)} instead
1198 */
1199 @Deprecated
1200 protected JsonParser _createJsonParser(Reader r, IOContext ctxt) throws IOException, JsonParseException {
Tatu Salorantaf15531c2011-12-22 23:00:40 -08001201 return new ReaderBasedJsonParser(ctxt, _parserFeatures, r, _objectCodec,
Tatu07351902012-01-19 13:12:13 -08001202 _rootCharSymbols.makeChild(isEnabled(JsonFactory.Feature.CANONICALIZE_FIELD_NAMES),
1203 isEnabled(JsonFactory.Feature.INTERN_FIELD_NAMES)));
Tatu Salorantaf15531c2011-12-22 23:00:40 -08001204 }
1205
1206 /**
1207 * Overridable factory method that actually instantiates parser
1208 * using given {@link Reader} object for reading content
1209 * passed as raw byte array.
1210 *<p>
1211 * This method is specifically designed to remain
1212 * compatible between minor versions so that sub-classes can count
1213 * on it being called as expected. That is, it is part of official
1214 * interface from sub-class perspective, although not a public
1215 * method available to users of factory implementations.
1216 */
Tatu Salorantaeeb2fbd2012-05-28 22:00:08 -07001217 protected JsonParser _createParser(byte[] data, int offset, int len, IOContext ctxt)
Tatu Salorantaf15531c2011-12-22 23:00:40 -08001218 throws IOException, JsonParseException
1219 {
Tatu Salorantaeeb2fbd2012-05-28 22:00:08 -07001220 /* NOTE: MUST call the deprecated method until it is deleted, just so
1221 * that override still works as expected, for now.
1222 */
1223 return _createJsonParser(data, offset, len, ctxt);
1224 }
1225
1226 /**
1227 * @deprecated since 2.1 -- use {@link #_createParser(byte[], int, int, IOContext)} instead
1228 */
1229 @Deprecated
1230 protected JsonParser _createJsonParser(byte[] data, int offset, int len, IOContext ctxt) throws IOException, JsonParseException {
Tatu Salorantaf15531c2011-12-22 23:00:40 -08001231 return new ByteSourceJsonBootstrapper(ctxt, data, offset, len).constructParser(_parserFeatures,
Tatu07351902012-01-19 13:12:13 -08001232 _objectCodec, _rootByteSymbols, _rootCharSymbols,
1233 isEnabled(JsonFactory.Feature.CANONICALIZE_FIELD_NAMES),
1234 isEnabled(JsonFactory.Feature.INTERN_FIELD_NAMES));
Tatu Salorantaf15531c2011-12-22 23:00:40 -08001235 }
Tatu Salorantaeeb2fbd2012-05-28 22:00:08 -07001236
Tatu Salorantaf15531c2011-12-22 23:00:40 -08001237 /*
1238 /**********************************************************
1239 /* Factory methods used by factory for creating generator instances,
1240 /* overridable by sub-classes
1241 /**********************************************************
1242 */
1243
1244 /**
1245 * Overridable factory method that actually instantiates generator for
1246 * given {@link Writer} and context object.
1247 *<p>
1248 * This method is specifically designed to remain
1249 * compatible between minor versions so that sub-classes can count
1250 * on it being called as expected. That is, it is part of official
1251 * interface from sub-class perspective, although not a public
1252 * method available to users of factory implementations.
1253 */
Tatu Salorantaeeb2fbd2012-05-28 22:00:08 -07001254 protected JsonGenerator _createGenerator(Writer out, IOContext ctxt)
1255 throws IOException
1256 {
1257 /* NOTE: MUST call the deprecated method until it is deleted, just so
1258 * that override still works as expected, for now.
1259 */
1260 return _createJsonGenerator(out, ctxt);
1261 }
1262
1263 /**
Tatu Salorantaec300272012-06-28 15:08:51 -07001264 * @deprecated since 2.1 -- use {@link #_createGenerator(Writer, IOContext)} instead
Tatu Salorantaeeb2fbd2012-05-28 22:00:08 -07001265 */
1266 @Deprecated
Tatu Salorantaf15531c2011-12-22 23:00:40 -08001267 protected JsonGenerator _createJsonGenerator(Writer out, IOContext ctxt)
1268 throws IOException
1269 {
Tatu Salorantae6dfc692012-09-28 15:34:05 -07001270 WriterBasedJsonGenerator gen = new WriterBasedJsonGenerator(ctxt,
1271 _generatorFeatures, _objectCodec, out);
Tatu Salorantaf15531c2011-12-22 23:00:40 -08001272 if (_characterEscapes != null) {
1273 gen.setCharacterEscapes(_characterEscapes);
1274 }
Tatu Salorantae6dfc692012-09-28 15:34:05 -07001275 SerializableString rootSep = _rootValueSeparator;
1276 if (rootSep != DEFAULT_ROOT_VALUE_SEPARATOR) {
1277 gen.setRootValueSeparator(rootSep);
1278 }
Tatu Salorantaf15531c2011-12-22 23:00:40 -08001279 return gen;
1280 }
1281
1282 /**
1283 * Overridable factory method that actually instantiates generator for
1284 * given {@link OutputStream} and context object, using UTF-8 encoding.
1285 *<p>
1286 * This method is specifically designed to remain
1287 * compatible between minor versions so that sub-classes can count
1288 * on it being called as expected. That is, it is part of official
1289 * interface from sub-class perspective, although not a public
1290 * method available to users of factory implementations.
1291 */
Tatu Salorantaeeb2fbd2012-05-28 22:00:08 -07001292 protected JsonGenerator _createUTF8Generator(OutputStream out, IOContext ctxt) throws IOException {
1293 return _createUTF8JsonGenerator(out, ctxt);
1294 }
1295
1296 /**
Tatu Salorantaec300272012-06-28 15:08:51 -07001297 * @deprecated since 2.1
Tatu Salorantaeeb2fbd2012-05-28 22:00:08 -07001298 */
1299 @Deprecated
Tatu Salorantaf15531c2011-12-22 23:00:40 -08001300 protected JsonGenerator _createUTF8JsonGenerator(OutputStream out, IOContext ctxt)
1301 throws IOException
1302 {
Tatu Salorantae6dfc692012-09-28 15:34:05 -07001303 UTF8JsonGenerator gen = new UTF8JsonGenerator(ctxt,
1304 _generatorFeatures, _objectCodec, out);
Tatu Salorantaf15531c2011-12-22 23:00:40 -08001305 if (_characterEscapes != null) {
1306 gen.setCharacterEscapes(_characterEscapes);
1307 }
Tatu Salorantae6dfc692012-09-28 15:34:05 -07001308 SerializableString rootSep = _rootValueSeparator;
1309 if (rootSep != DEFAULT_ROOT_VALUE_SEPARATOR) {
1310 gen.setRootValueSeparator(rootSep);
1311 }
Tatu Salorantaf15531c2011-12-22 23:00:40 -08001312 return gen;
1313 }
1314
1315 protected Writer _createWriter(OutputStream out, JsonEncoding enc, IOContext ctxt) throws IOException
1316 {
1317 // note: this should not get called any more (caller checks, dispatches)
1318 if (enc == JsonEncoding.UTF8) { // We have optimized writer for UTF-8
1319 return new UTF8Writer(ctxt, out);
1320 }
1321 // not optimal, but should do unless we really care about UTF-16/32 encoding speed
1322 return new OutputStreamWriter(out, enc.getJavaName());
1323 }
1324
1325 /*
1326 /**********************************************************
1327 /* Internal factory methods, other
1328 /**********************************************************
1329 */
1330
1331 /**
1332 * Overridable factory method that actually instantiates desired
1333 * context object.
1334 */
1335 protected IOContext _createContext(Object srcRef, boolean resourceManaged)
1336 {
1337 return new IOContext(_getBufferRecycler(), srcRef, resourceManaged);
1338 }
1339
1340 /**
1341 * Method used by factory to create buffer recycler instances
1342 * for parsers and generators.
1343 *<p>
1344 * Note: only public to give access for <code>ObjectMapper</code>
1345 */
1346 public BufferRecycler _getBufferRecycler()
1347 {
1348 SoftReference<BufferRecycler> ref = _recyclerRef.get();
1349 BufferRecycler br = (ref == null) ? null : ref.get();
1350
1351 if (br == null) {
1352 br = new BufferRecycler();
1353 _recyclerRef.set(new SoftReference<BufferRecycler>(br));
1354 }
1355 return br;
1356 }
1357
1358 /**
1359 * Helper methods used for constructing an optimal stream for
1360 * parsers to use, when input is to be read from an URL.
1361 * This helps when reading file content via URL.
1362 */
1363 protected InputStream _optimizedStreamFromURL(URL url)
1364 throws IOException
1365 {
1366 if ("file".equals(url.getProtocol())) {
1367 /* Can not do this if the path refers
1368 * to a network drive on windows. This fixes the problem;
1369 * might not be needed on all platforms (NFS?), but should not
1370 * matter a lot: performance penalty of extra wrapping is more
1371 * relevant when accessing local file system.
1372 */
1373 String host = url.getHost();
1374 if (host == null || host.length() == 0) {
1375 return new FileInputStream(url.getPath());
1376 }
1377 }
1378 return url.openStream();
1379 }
1380}