blob: 875e271803d068107a850d43d7e76cf77f76082c [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 Salorantaf15531c2011-12-22 23:00:40 -080028
29/**
30 * The main factory class of Jackson package, used to configure and
31 * construct reader (aka parser, {@link JsonParser})
32 * and writer (aka generator, {@link JsonGenerator})
33 * instances.
34 *<p>
35 * Factory instances are thread-safe and reusable after configuration
36 * (if any). Typically applications and services use only a single
37 * globally shared factory instance, unless they need differently
38 * configured factories. Factory reuse is important if efficiency matters;
39 * most recycling of expensive construct is done on per-factory basis.
40 *<p>
41 * Creation of a factory instance is a light-weight operation,
42 * and since there is no need for pluggable alternative implementations
43 * (as there is no "standard" JSON processor API to implement),
44 * the default constructor is used for constructing factory
45 * instances.
46 *
47 * @author Tatu Saloranta
48 */
49public class JsonFactory implements Versioned
50{
51 /**
52 * Name used to identify JSON format
53 * (and returned by {@link #getFormatName()}
54 */
55 public final static String FORMAT_NAME_JSON = "JSON";
56
57 /**
Tatu07351902012-01-19 13:12:13 -080058 * Bitfield (set of flags) of all factory features that are enabled by default.
59 */
60 protected final static int DEFAULT_FACTORY_FEATURE_FLAGS = JsonFactory.Feature.collectDefaults();
61
62 /**
Tatu Salorantaf15531c2011-12-22 23:00:40 -080063 * Bitfield (set of flags) of all parser features that are enabled
64 * by default.
65 */
Tatu07351902012-01-19 13:12:13 -080066 protected final static int DEFAULT_PARSER_FEATURE_FLAGS = JsonParser.Feature.collectDefaults();
67
Tatu Salorantaf15531c2011-12-22 23:00:40 -080068 /**
69 * Bitfield (set of flags) of all generator features that are enabled
70 * by default.
71 */
Tatu07351902012-01-19 13:12:13 -080072 protected final static int DEFAULT_GENERATOR_FEATURE_FLAGS = JsonGenerator.Feature.collectDefaults();
Tatu Salorantaf15531c2011-12-22 23:00:40 -080073
Tatu07351902012-01-19 13:12:13 -080074 /**
75 * Enumeration that defines all on/off features that can only be
76 * changed for {@link JsonFactory}.
77 */
78 public enum Feature {
79
80 // // // Symbol handling (interning etc)
81
82 /**
83 * Feature that determines whether JSON object field names are
84 * to be canonicalized using {@link String#intern} or not:
85 * if enabled, all field names will be intern()ed (and caller
86 * can count on this being true for all such names); if disabled,
87 * no intern()ing is done. There may still be basic
88 * canonicalization (that is, same String will be used to represent
89 * all identical object property names for a single document).
90 *<p>
91 * Note: this setting only has effect if
92 * {@link #CANONICALIZE_FIELD_NAMES} is true -- otherwise no
93 * canonicalization of any sort is done.
94 *<p>
95 * This setting is enabled by default.
96 */
97 INTERN_FIELD_NAMES(true),
98
99 /**
100 * Feature that determines whether JSON object field names are
101 * to be canonicalized (details of how canonicalization is done
102 * then further specified by
103 * {@link #INTERN_FIELD_NAMES}).
104 *<p>
105 * This setting is enabled by default.
106 */
107 CANONICALIZE_FIELD_NAMES(true)
108
109 ;
110
111 /**
112 * Whether feature is enabled or disabled by default.
113 */
114 private final boolean _defaultState;
115
116 /**
117 * Method that calculates bit set (flags) of all features that
118 * are enabled by default.
119 */
120 public static int collectDefaults()
121 {
122 int flags = 0;
123 for (Feature f : values()) {
124 if (f.enabledByDefault()) {
125 flags |= f.getMask();
126 }
127 }
128 return flags;
129 }
130
131 private Feature(boolean defaultState)
132 {
133 _defaultState = defaultState;
134 }
135
136 public boolean enabledByDefault() { return _defaultState; }
137
138 public boolean enabledIn(int flags) { return (flags & getMask()) != 0; }
139
140 public int getMask() { return (1 << ordinal()); }
141 }
Tatu Salorantaf15531c2011-12-22 23:00:40 -0800142 /*
143 /**********************************************************
144 /* Buffer, symbol table management
145 /**********************************************************
146 */
147
148 /**
149 * This <code>ThreadLocal</code> contains a {@link java.lang.ref.SoftRerefence}
150 * to a {@link BufferRecycler} used to provide a low-cost
151 * buffer recycling between reader and writer instances.
152 */
153 final protected static ThreadLocal<SoftReference<BufferRecycler>> _recyclerRef
154 = new ThreadLocal<SoftReference<BufferRecycler>>();
155
156 /**
157 * Each factory comes equipped with a shared root symbol table.
158 * It should not be linked back to the original blueprint, to
159 * avoid contents from leaking between factories.
160 */
161 protected CharsToNameCanonicalizer _rootCharSymbols = CharsToNameCanonicalizer.createRoot();
162
163 /**
164 * Alternative to the basic symbol table, some stream-based
165 * parsers use different name canonicalization method.
166 *<p>
167 * TODO: should clean up this; looks messy having 2 alternatives
168 * with not very clear differences.
169 */
170 protected BytesToNameCanonicalizer _rootByteSymbols = BytesToNameCanonicalizer.createRoot();
171
172 /*
173 /**********************************************************
174 /* Configuration
175 /**********************************************************
176 */
177
178 /**
179 * Object that implements conversion functionality between
180 * Java objects and JSON content. For base JsonFactory implementation
181 * usually not set by default, but can be explicitly set.
182 * Sub-classes (like @link org.codehaus.jackson.map.MappingJsonFactory}
183 * usually provide an implementation.
184 */
185 protected ObjectCodec _objectCodec;
186
187 /**
Tatu07351902012-01-19 13:12:13 -0800188 * Currently enabled factory features.
189 */
190 protected int _factoryFeatures = DEFAULT_FACTORY_FEATURE_FLAGS;
191
192 /**
Tatu Salorantaf15531c2011-12-22 23:00:40 -0800193 * Currently enabled parser features.
194 */
195 protected int _parserFeatures = DEFAULT_PARSER_FEATURE_FLAGS;
196
197 /**
198 * Currently enabled generator features.
199 */
200 protected int _generatorFeatures = DEFAULT_GENERATOR_FEATURE_FLAGS;
201
202 /**
203 * Definition of custom character escapes to use for generators created
204 * by this factory, if any. If null, standard data format specific
205 * escapes are used.
206 */
207 protected CharacterEscapes _characterEscapes;
208
209 /**
210 * Optional helper object that may decorate input sources, to do
211 * additional processing on input during parsing.
212 */
213 protected InputDecorator _inputDecorator;
214
215 /**
216 * Optional helper object that may decorate output object, to do
217 * additional processing on output during content generation.
218 */
219 protected OutputDecorator _outputDecorator;
220
221 /*
222 /**********************************************************
223 /* Construction
224 /**********************************************************
225 */
226
227 /**
228 * Default constructor used to create factory instances.
229 * Creation of a factory instance is a light-weight operation,
230 * but it is still a good idea to reuse limited number of
231 * factory instances (and quite often just a single instance):
232 * factories are used as context for storing some reused
233 * processing objects (such as symbol tables parsers use)
234 * and this reuse only works within context of a single
235 * factory instance.
236 */
237 public JsonFactory() { this(null); }
238
239 public JsonFactory(ObjectCodec oc) { _objectCodec = oc; }
240
241 /*
242 /**********************************************************
243 /* Format detection functionality (since 1.8)
244 /**********************************************************
245 */
246
247 /**
248 * Method that returns short textual id identifying format
249 * this factory supports.
250 *<p>
251 * Note: sub-classes should override this method; default
252 * implementation will return null for all sub-classes
253 */
254 public String getFormatName()
255 {
256 /* Somewhat nasty check: since we can't make this abstract
257 * (due to backwards compatibility concerns), need to prevent
258 * format name "leakage"
259 */
260 if (getClass() == JsonFactory.class) {
261 return FORMAT_NAME_JSON;
262 }
263 return null;
264 }
265
266 public MatchStrength hasFormat(InputAccessor acc) throws IOException
267 {
268 // since we can't keep this abstract, only implement for "vanilla" instance
269 if (getClass() == JsonFactory.class) {
270 return hasJSONFormat(acc);
271 }
272 return null;
273 }
274
275 protected MatchStrength hasJSONFormat(InputAccessor acc) throws IOException
276 {
277 return ByteSourceJsonBootstrapper.hasJSONFormat(acc);
278 }
279
280 /*
281 /**********************************************************
282 /* Versioned
283 /**********************************************************
284 */
285
Tatu Salorantae9b48512012-04-17 10:22:07 -0700286// @Override
Tatu Salorantaf15531c2011-12-22 23:00:40 -0800287 public Version version() {
Tatu Saloranta5a1bd992011-12-28 23:18:23 -0800288 return CoreVersion.instance.version();
Tatu Salorantaf15531c2011-12-22 23:00:40 -0800289 }
290
291 /*
292 /**********************************************************
Tatu07351902012-01-19 13:12:13 -0800293 /* Configuration, factory features
Tatu Salorantaf15531c2011-12-22 23:00:40 -0800294 /**********************************************************
295 */
296
297 /**
298 * Method for enabling or disabling specified parser feature
299 * (check {@link JsonParser.Feature} for list of features)
300 */
Tatu07351902012-01-19 13:12:13 -0800301 public final JsonFactory configure(JsonFactory.Feature f, boolean state) {
302 return state ? enable(f) : disable(f);
303 }
304
305 /**
306 * Method for enabling specified parser feature
307 * (check {@link JsonFactory.Feature} for list of features)
308 */
309 public JsonFactory enable(JsonFactory.Feature f) {
310 _factoryFeatures |= f.getMask();
Tatu Salorantaf15531c2011-12-22 23:00:40 -0800311 return this;
312 }
313
314 /**
Tatu07351902012-01-19 13:12:13 -0800315 * Method for disabling specified parser features
316 * (check {@link JsonFactory.Feature} for list of features)
317 */
318 public JsonFactory disable(JsonFactory.Feature f) {
319 _factoryFeatures &= ~f.getMask();
320 return this;
321 }
322
323 /**
324 * Checked whether specified parser feature is enabled.
325 */
326 public final boolean isEnabled(JsonFactory.Feature f) {
327 return (_factoryFeatures & f.getMask()) != 0;
328 }
329
330 /*
331 /**********************************************************
332 /* Configuration, parser configuration
333 /**********************************************************
334 */
335
336 /**
337 * Method for enabling or disabling specified parser feature
338 * (check {@link JsonParser.Feature} for list of features)
339 */
340 public final JsonFactory configure(JsonParser.Feature f, boolean state) {
341 return state ? enable(f) : disable(f);
342 }
343
344 /**
Tatu Salorantaf15531c2011-12-22 23:00:40 -0800345 * Method for enabling specified parser feature
346 * (check {@link JsonParser.Feature} for list of features)
347 */
348 public JsonFactory enable(JsonParser.Feature f) {
349 _parserFeatures |= f.getMask();
350 return this;
351 }
352
353 /**
354 * Method for disabling specified parser features
355 * (check {@link JsonParser.Feature} for list of features)
356 */
357 public JsonFactory disable(JsonParser.Feature f) {
358 _parserFeatures &= ~f.getMask();
359 return this;
360 }
361
362 /**
363 * Checked whether specified parser feature is enabled.
364 */
365 public final boolean isEnabled(JsonParser.Feature f) {
366 return (_parserFeatures & f.getMask()) != 0;
367 }
368
369 /**
370 * Method for getting currently configured input decorator (if any;
371 * there is no default decorator).
372 */
373 public InputDecorator getInputDecorator() {
374 return _inputDecorator;
375 }
376
377 /**
378 * Method for overriding currently configured input decorator
379 */
380 public JsonFactory setInputDecorator(InputDecorator d) {
381 _inputDecorator = d;
382 return this;
383 }
384
385 /*
386 /**********************************************************
387 /* Configuration, generator settings
388 /**********************************************************
389 */
390
391 /**
392 * Method for enabling or disabling specified generator feature
393 * (check {@link JsonGenerator.Feature} for list of features)
394 */
395 public final JsonFactory configure(JsonGenerator.Feature f, boolean state) {
Tatu07351902012-01-19 13:12:13 -0800396 return state ? enable(f) : disable(f);
Tatu Salorantaf15531c2011-12-22 23:00:40 -0800397 }
398
399
400 /**
401 * Method for enabling specified generator features
402 * (check {@link JsonGenerator.Feature} for list of features)
403 */
404 public JsonFactory enable(JsonGenerator.Feature f) {
405 _generatorFeatures |= f.getMask();
406 return this;
407 }
408
409 /**
410 * Method for disabling specified generator feature
411 * (check {@link JsonGenerator.Feature} for list of features)
412 */
413 public JsonFactory disable(JsonGenerator.Feature f) {
414 _generatorFeatures &= ~f.getMask();
415 return this;
416 }
417
418 /**
419 * Check whether specified generator feature is enabled.
420 */
421 public final boolean isEnabled(JsonGenerator.Feature f) {
422 return (_generatorFeatures & f.getMask()) != 0;
423 }
424
425 /**
426 * Method for accessing custom escapes factory uses for {@link JsonGenerator}s
427 * it creates.
428 */
429 public CharacterEscapes getCharacterEscapes() {
430 return _characterEscapes;
431 }
432
433 /**
434 * Method for defining custom escapes factory uses for {@link JsonGenerator}s
435 * it creates.
436 */
437 public JsonFactory setCharacterEscapes(CharacterEscapes esc) {
438 _characterEscapes = esc;
439 return this;
440 }
441
442 /**
443 * Method for getting currently configured output decorator (if any;
444 * there is no default decorator).
445 */
446 public OutputDecorator getOutputDecorator() {
447 return _outputDecorator;
448 }
449
450 /**
451 * Method for overriding currently configured output decorator
452 */
453 public JsonFactory setOutputDecorator(OutputDecorator d) {
454 _outputDecorator = d;
455 return this;
456 }
457
458 /*
459 /**********************************************************
460 /* Configuration, other
461 /**********************************************************
462 */
463
464 /**
465 * Method for associating a {@link ObjectCodec} (typically
Tatu Salorantad77350e2011-12-22 23:13:13 -0800466 * a <code>com.fasterxml.jackson.databind.ObjectMapper</code>)
467 * with this factory (and more importantly, parsers and generators
Tatu Salorantaf15531c2011-12-22 23:00:40 -0800468 * it constructs). This is needed to use data-binding methods
469 * of {@link JsonParser} and {@link JsonGenerator} instances.
470 */
471 public JsonFactory setCodec(ObjectCodec oc) {
472 _objectCodec = oc;
473 return this;
474 }
475
476 public ObjectCodec getCodec() { return _objectCodec; }
477
478 /*
479 /**********************************************************
Tatu Salorantafeaabd12012-07-22 23:03:41 -0700480 /* Parser factories (new ones, as per [Issue-25])
Tatu Salorantaf15531c2011-12-22 23:00:40 -0800481 /**********************************************************
482 */
483
484 /**
485 * Method for constructing JSON parser instance to parse
486 * contents of specified file. Encoding is auto-detected
487 * from contents according to JSON specification recommended
488 * mechanism.
489 *<p>
490 * Underlying input stream (needed for reading contents)
491 * will be <b>owned</b> (and managed, i.e. closed as need be) by
492 * the parser, since caller has no access to it.
493 *
494 * @param f File that contains JSON content to parse
Tatu Salorantafeaabd12012-07-22 23:03:41 -0700495 *
496 * @since 2.1
497 */
498 public JsonParser createParser(File f)
499 throws IOException, JsonParseException
500 {
501 // Must delegate to old version, until 2.2
502 // TODO: change direction in 2.2; after ensuring impls support new method
503 return createJsonParser(f);
504 }
505
506 /**
507 * Method for constructing JSON parser instance to parse
508 * contents of resource reference by given URL.
509 * Encoding is auto-detected
510 * from contents according to JSON specification recommended
511 * mechanism.
512 *<p>
513 * Underlying input stream (needed for reading contents)
514 * will be <b>owned</b> (and managed, i.e. closed as need be) by
515 * the parser, since caller has no access to it.
516 *
517 * @param url URL pointing to resource that contains JSON content to parse
518 *
519 * @since 2.1
520 */
521 public JsonParser createParser(URL url)
522 throws IOException, JsonParseException
523 {
524 // Must delegate to old version, until 2.2
525 // TODO: change direction in 2.2; after ensuring impls support new method
526 return createJsonParser(url);
527 }
528
529 /**
530 * Method for constructing JSON parser instance to parse
531 * the contents accessed via specified input stream.
532 *<p>
533 * The input stream will <b>not be owned</b> by
534 * the parser, it will still be managed (i.e. closed if
535 * end-of-stream is reacher, or parser close method called)
536 * if (and only if) {@link com.fasterxml.jackson.core.JsonParser.Feature#AUTO_CLOSE_SOURCE}
537 * is enabled.
538 *<p>
539 * Note: no encoding argument is taken since it can always be
540 * auto-detected as suggested by JSON RFC.
541 *
542 * @param in InputStream to use for reading JSON content to parse
543 *
544 * @since 2.1
545 */
546 public JsonParser createParser(InputStream in)
547 throws IOException, JsonParseException
548 {
549 // Must delegate to old version, until 2.2
550 // TODO: change direction in 2.2; after ensuring impls support new method
551 return createJsonParser(in);
552 }
553
554 /**
555 * Method for constructing parser for parsing
556 * the contents accessed via specified Reader.
557 <p>
558 * The read stream will <b>not be owned</b> by
559 * the parser, it will still be managed (i.e. closed if
560 * end-of-stream is reacher, or parser close method called)
561 * if (and only if) {@link com.fasterxml.jackson.core.JsonParser.Feature#AUTO_CLOSE_SOURCE}
562 * is enabled.
563 *
564 * @param r Reader to use for reading JSON content to parse
565 *
566 * @since 2.1
567 */
568 public JsonParser createParser(Reader r)
569 throws IOException, JsonParseException
570 {
571 // Must delegate to old version, until 2.2
572 // TODO: change direction in 2.2; after ensuring impls support new method
573 return createJsonParser(r);
574 }
575
576 /**
577 * Method for constructing parser for parsing
578 * the contents of given byte array.
579 *
580 * @since 2.1
581 */
582 public JsonParser createParser(byte[] data)
583 throws IOException, JsonParseException
584 {
585 // Must delegate to old version, until 2.2
586 // TODO: change direction in 2.2; after ensuring impls support new method
587 return createJsonParser(data);
588 }
589
590 /**
591 * Method for constructing parser for parsing
592 * the contents of given byte array.
593 *
594 * @param data Buffer that contains data to parse
595 * @param offset Offset of the first data byte within buffer
596 * @param len Length of contents to parse within buffer
597 *
598 * @since 2.1
599 */
600 public JsonParser createParser(byte[] data, int offset, int len)
601 throws IOException, JsonParseException
602 {
603 // Must delegate to old version, until 2.2
604 // TODO: change direction in 2.2; after ensuring impls support new method
605 return createJsonParser(data, offset, len);
606 }
607
608 /**
609 * Method for constructing parser for parsing
610 * contents of given String.
611 *
612 * @since 2.1
613 */
614 public JsonParser createParser(String content)
615 throws IOException, JsonParseException
616 {
617 // Must delegate to old version, until 2.2
618 // TODO: change direction in 2.2; after ensuring impls support new method
619 return createJsonParser(content);
620 }
621
622 /*
623 /**********************************************************
624 /* Parser factories (old ones, as per [Issue-25])
625 /**********************************************************
626 */
627
628 /**
629 * Method for constructing JSON parser instance to parse
630 * contents of specified file. Encoding is auto-detected
631 * from contents according to JSON specification recommended
632 * mechanism.
633 *<p>
634 * Underlying input stream (needed for reading contents)
635 * will be <b>owned</b> (and managed, i.e. closed as need be) by
636 * the parser, since caller has no access to it.
637 *<p>
638 * NOTE: as of 2.1, should not be used (will be deprecated in 2.2);
639 * instead, should call <code>createParser</code>.
640 *
641 * @param f File that contains JSON content to parse
Tatu Salorantaf15531c2011-12-22 23:00:40 -0800642 */
643 public JsonParser createJsonParser(File f)
644 throws IOException, JsonParseException
645 {
646 // true, since we create InputStream from File
647 IOContext ctxt = _createContext(f, true);
648 InputStream in = new FileInputStream(f);
649 // [JACKSON-512]: allow wrapping with InputDecorator
650 if (_inputDecorator != null) {
651 in = _inputDecorator.decorate(ctxt, in);
652 }
Tatu Salorantaeeb2fbd2012-05-28 22:00:08 -0700653 return _createParser(in, ctxt);
Tatu Salorantaf15531c2011-12-22 23:00:40 -0800654 }
655
656 /**
657 * Method for constructing JSON parser instance to parse
658 * contents of resource reference by given URL.
659 * Encoding is auto-detected
660 * from contents according to JSON specification recommended
661 * mechanism.
662 *<p>
663 * Underlying input stream (needed for reading contents)
664 * will be <b>owned</b> (and managed, i.e. closed as need be) by
665 * the parser, since caller has no access to it.
Tatu Salorantafeaabd12012-07-22 23:03:41 -0700666 *<p>
667 * NOTE: as of 2.1, should not be used (will be deprecated in 2.2);
668 * instead, should call <code>createParser</code>.
Tatu Salorantaf15531c2011-12-22 23:00:40 -0800669 *
670 * @param url URL pointing to resource that contains JSON content to parse
671 */
672 public JsonParser createJsonParser(URL url)
673 throws IOException, JsonParseException
674 {
675 // true, since we create InputStream from URL
676 IOContext ctxt = _createContext(url, true);
677 InputStream in = _optimizedStreamFromURL(url);
678 // [JACKSON-512]: allow wrapping with InputDecorator
679 if (_inputDecorator != null) {
680 in = _inputDecorator.decorate(ctxt, in);
681 }
Tatu Salorantaeeb2fbd2012-05-28 22:00:08 -0700682 return _createParser(in, ctxt);
Tatu Salorantaf15531c2011-12-22 23:00:40 -0800683 }
684
685 /**
686 * Method for constructing JSON parser instance to parse
687 * the contents accessed via specified input stream.
688 *<p>
689 * The input stream will <b>not be owned</b> by
690 * the parser, it will still be managed (i.e. closed if
691 * end-of-stream is reacher, or parser close method called)
692 * if (and only if) {@link com.fasterxml.jackson.core.JsonParser.Feature#AUTO_CLOSE_SOURCE}
693 * is enabled.
694 *<p>
695 * Note: no encoding argument is taken since it can always be
Tatu Salorantafeaabd12012-07-22 23:03:41 -0700696 * auto-detected as suggested by JSON RFC.
697 *<p>
698 * NOTE: as of 2.1, should not be used (will be deprecated in 2.2);
699 * instead, should call <code>createParser</code>.
Tatu Salorantaf15531c2011-12-22 23:00:40 -0800700 *
701 * @param in InputStream to use for reading JSON content to parse
702 */
703 public JsonParser createJsonParser(InputStream in)
704 throws IOException, JsonParseException
705 {
706 IOContext ctxt = _createContext(in, false);
707 // [JACKSON-512]: allow wrapping with InputDecorator
708 if (_inputDecorator != null) {
709 in = _inputDecorator.decorate(ctxt, in);
710 }
Tatu Salorantaeeb2fbd2012-05-28 22:00:08 -0700711 return _createParser(in, ctxt);
Tatu Salorantaf15531c2011-12-22 23:00:40 -0800712 }
713
714 /**
715 * Method for constructing parser for parsing
716 * the contents accessed via specified Reader.
717 <p>
718 * The read stream will <b>not be owned</b> by
719 * the parser, it will still be managed (i.e. closed if
720 * end-of-stream is reacher, or parser close method called)
721 * if (and only if) {@link com.fasterxml.jackson.core.JsonParser.Feature#AUTO_CLOSE_SOURCE}
722 * is enabled.
723 *<p>
Tatu Salorantafeaabd12012-07-22 23:03:41 -0700724 * NOTE: as of 2.1, should not be used (will be deprecated in 2.2);
725 * instead, should call <code>createParser</code>.
Tatu Salorantaf15531c2011-12-22 23:00:40 -0800726 *
727 * @param r Reader to use for reading JSON content to parse
728 */
729 public JsonParser createJsonParser(Reader r)
730 throws IOException, JsonParseException
731 {
732 // false -> we do NOT own Reader (did not create it)
733 IOContext ctxt = _createContext(r, false);
734 // [JACKSON-512]: allow wrapping with InputDecorator
735 if (_inputDecorator != null) {
736 r = _inputDecorator.decorate(ctxt, r);
737 }
Tatu Saloranta3e5ff6d2012-06-27 18:46:43 -0700738 return _createParser(r, ctxt);
Tatu Salorantaf15531c2011-12-22 23:00:40 -0800739 }
740
741 /**
742 * Method for constructing parser for parsing
743 * the contents of given byte array.
Tatu Salorantafeaabd12012-07-22 23:03:41 -0700744 *<p>
745 * NOTE: as of 2.1, should not be used (will be deprecated in 2.2);
746 * instead, should call <code>createParser</code>.
Tatu Salorantaf15531c2011-12-22 23:00:40 -0800747 */
748 public JsonParser createJsonParser(byte[] data)
749 throws IOException, JsonParseException
750 {
751 IOContext ctxt = _createContext(data, true);
752 // [JACKSON-512]: allow wrapping with InputDecorator
753 if (_inputDecorator != null) {
754 InputStream in = _inputDecorator.decorate(ctxt, data, 0, data.length);
755 if (in != null) {
Tatu Salorantaeeb2fbd2012-05-28 22:00:08 -0700756 return _createParser(in, ctxt);
Tatu Salorantaf15531c2011-12-22 23:00:40 -0800757 }
758 }
Tatu Salorantaeeb2fbd2012-05-28 22:00:08 -0700759 return _createParser(data, 0, data.length, ctxt);
Tatu Salorantaf15531c2011-12-22 23:00:40 -0800760 }
761
762 /**
763 * Method for constructing parser for parsing
764 * the contents of given byte array.
Tatu Salorantafeaabd12012-07-22 23:03:41 -0700765 *<p>
766 * NOTE: as of 2.1, should not be used (will be deprecated in 2.2);
767 * instead, should call <code>createParser</code>.
Tatu Salorantaf15531c2011-12-22 23:00:40 -0800768 *
769 * @param data Buffer that contains data to parse
770 * @param offset Offset of the first data byte within buffer
771 * @param len Length of contents to parse within buffer
772 */
773 public JsonParser createJsonParser(byte[] data, int offset, int len)
774 throws IOException, JsonParseException
775 {
776 IOContext ctxt = _createContext(data, true);
777 // [JACKSON-512]: allow wrapping with InputDecorator
778 if (_inputDecorator != null) {
779 InputStream in = _inputDecorator.decorate(ctxt, data, offset, len);
780 if (in != null) {
Tatu Salorantaeeb2fbd2012-05-28 22:00:08 -0700781 return _createParser(in, ctxt);
Tatu Salorantaf15531c2011-12-22 23:00:40 -0800782 }
783 }
Tatu Salorantaeeb2fbd2012-05-28 22:00:08 -0700784 return _createParser(data, offset, len, ctxt);
Tatu Salorantaf15531c2011-12-22 23:00:40 -0800785 }
786
787 /**
788 * Method for constructing parser for parsing
789 * contents of given String.
Tatu Salorantafeaabd12012-07-22 23:03:41 -0700790 *<p>
791 * NOTE: as of 2.1, should not be used (will be deprecated in 2.2);
792 * instead, should call <code>createParser</code>.
Tatu Salorantaf15531c2011-12-22 23:00:40 -0800793 */
794 public JsonParser createJsonParser(String content)
795 throws IOException, JsonParseException
796 {
Tatu Saloranta3e5ff6d2012-06-27 18:46:43 -0700797 Reader r = new StringReader(content);
Tatu Salorantaf15531c2011-12-22 23:00:40 -0800798 // true -> we own the Reader (and must close); not a big deal
799 IOContext ctxt = _createContext(r, true);
800 // [JACKSON-512]: allow wrapping with InputDecorator
801 if (_inputDecorator != null) {
802 r = _inputDecorator.decorate(ctxt, r);
803 }
Tatu Saloranta3e5ff6d2012-06-27 18:46:43 -0700804 return _createParser(r, ctxt);
Tatu Salorantaf15531c2011-12-22 23:00:40 -0800805 }
806
807 /*
808 /**********************************************************
Tatu Salorantafeaabd12012-07-22 23:03:41 -0700809 /* Generator factories, new (as per [Issue-25]
Tatu Salorantaf15531c2011-12-22 23:00:40 -0800810 /**********************************************************
811 */
812
813 /**
814 * Method for constructing JSON generator for writing JSON content
815 * using specified output stream.
816 * Encoding to use must be specified, and needs to be one of available
817 * types (as per JSON specification).
818 *<p>
819 * Underlying stream <b>is NOT owned</b> by the generator constructed,
820 * so that generator will NOT close the output stream when
821 * {@link JsonGenerator#close} is called (unless auto-closing
822 * feature,
823 * {@link com.fasterxml.jackson.core.JsonGenerator.Feature#AUTO_CLOSE_TARGET}
824 * is enabled).
825 * Using application needs to close it explicitly if this is the case.
826 *<p>
827 * Note: there are formats that use fixed encoding (like most binary data formats)
828 * and that ignore passed in encoding.
Tatu Salorantafeaabd12012-07-22 23:03:41 -0700829 *<p>
830 * NOTE: starting with 2.1, should not be used (will be deprecated in 2.2);
831 * instead, should call <code>createGenerator</code>.
832 *
833 * @since 2.1 Will eventually replace <code>createJsonGenerator</code> variant.
834 *
835 * @param out OutputStream to use for writing JSON content
836 * @param enc Character encoding to use
837 */
838 public JsonGenerator createGenerator(OutputStream out, JsonEncoding enc)
839 throws IOException
840 {
841 return createJsonGenerator(out, enc);
842 }
843
844 /**
845 * Method for constructing JSON generator for writing JSON content
846 * using specified Writer.
847 *<p>
848 * Underlying stream <b>is NOT owned</b> by the generator constructed,
849 * so that generator will NOT close the Reader when
850 * {@link JsonGenerator#close} is called (unless auto-closing
851 * feature,
852 * {@link com.fasterxml.jackson.core.JsonGenerator.Feature#AUTO_CLOSE_TARGET} is enabled).
853 * Using application needs to close it explicitly.
854 *<p>
855 * NOTE: starting with 2.1, should not be used (will be deprecated in 2.2);
856 * instead, should call <code>createGenerator</code>.
857 *
858 * @since 2.1 Will eventually replace <code>createJsonGenerator</code> variant.
859 *
860 * @param out Writer to use for writing JSON content
861 */
862 public JsonGenerator createGenerator(Writer out)
863 throws IOException
864 {
865 return createJsonGenerator(out);
866 }
867
868 /**
869 * Convenience method for constructing generator that uses default
870 * encoding of the format (UTF-8 for JSON and most other data formats).
871 *<p>
872 * Note: there are formats that use fixed encoding (like most binary data formats).
873 *<p>
874 * NOTE: starting with 2.1, should not be used (will be deprecated in 2.2);
875 * instead, should call <code>createGenerator</code>.
876 *
877 * @since 2.1 Will eventually replace <code>createJsonGenerator</code> variant.
878 */
879 public JsonGenerator createGenerator(OutputStream out) throws IOException {
880 return createJsonGenerator(out);
881 }
882
883 /**
884 * Method for constructing JSON generator for writing JSON content
885 * to specified file, overwriting contents it might have (or creating
886 * it if such file does not yet exist).
887 * Encoding to use must be specified, and needs to be one of available
888 * types (as per JSON specification).
889 *<p>
890 * Underlying stream <b>is owned</b> by the generator constructed,
891 * i.e. generator will handle closing of file when
892 * {@link JsonGenerator#close} is called.
893 *<p>
894 * NOTE: starting with 2.1, should not be used (will be deprecated in 2.2);
895 * instead, should call <code>createGenerator</code>.
896 *
897 * @since 2.1 Will eventually replace <code>createJsonGenerator</code> variant.
898 *
899 * @param f File to write contents to
900 * @param enc Character encoding to use
901 */
902 public JsonGenerator createGenerator(File f, JsonEncoding enc)
903 throws IOException
904 {
905 return createJsonGenerator(f, enc);
906 }
907
908 /*
909 /**********************************************************
910 /* Generator factories, old (as per [Issue-25]
911 /**********************************************************
912 */
913
914 /**
915 * Method for constructing JSON generator for writing JSON content
916 * using specified output stream.
917 * Encoding to use must be specified, and needs to be one of available
918 * types (as per JSON specification).
919 *<p>
920 * Underlying stream <b>is NOT owned</b> by the generator constructed,
921 * so that generator will NOT close the output stream when
922 * {@link JsonGenerator#close} is called (unless auto-closing
923 * feature,
924 * {@link com.fasterxml.jackson.core.JsonGenerator.Feature#AUTO_CLOSE_TARGET}
925 * is enabled).
926 * Using application needs to close it explicitly if this is the case.
927 *<p>
928 * Note: there are formats that use fixed encoding (like most binary data formats)
929 * and that ignore passed in encoding.
930 *<p>
931 * NOTE: starting with 2.1, should not be used (will be deprecated in 2.2);
932 * instead, should call <code>createGenerator</code>.
Tatu Salorantaf15531c2011-12-22 23:00:40 -0800933 *
934 * @param out OutputStream to use for writing JSON content
935 * @param enc Character encoding to use
936 */
937 public JsonGenerator createJsonGenerator(OutputStream out, JsonEncoding enc)
938 throws IOException
939 {
940 // false -> we won't manage the stream unless explicitly directed to
941 IOContext ctxt = _createContext(out, false);
942 ctxt.setEncoding(enc);
943 if (enc == JsonEncoding.UTF8) {
944 // [JACKSON-512]: allow wrapping with _outputDecorator
945 if (_outputDecorator != null) {
946 out = _outputDecorator.decorate(ctxt, out);
947 }
948 return _createUTF8JsonGenerator(out, ctxt);
949 }
950 Writer w = _createWriter(out, enc, ctxt);
951 // [JACKSON-512]: allow wrapping with _outputDecorator
952 if (_outputDecorator != null) {
953 w = _outputDecorator.decorate(ctxt, w);
954 }
Tatu Salorantaeeb2fbd2012-05-28 22:00:08 -0700955 return _createGenerator(w, ctxt);
Tatu Salorantaf15531c2011-12-22 23:00:40 -0800956 }
957
958 /**
959 * Method for constructing JSON generator for writing JSON content
960 * using specified Writer.
961 *<p>
962 * Underlying stream <b>is NOT owned</b> by the generator constructed,
963 * so that generator will NOT close the Reader when
964 * {@link JsonGenerator#close} is called (unless auto-closing
965 * feature,
966 * {@link com.fasterxml.jackson.core.JsonGenerator.Feature#AUTO_CLOSE_TARGET} is enabled).
967 * Using application needs to close it explicitly.
Tatu Salorantafeaabd12012-07-22 23:03:41 -0700968 *<p>
969 * NOTE: starting with 2.1, should not be used (will be deprecated in 2.2);
970 * instead, should call <code>createGenerator</code>.
Tatu Salorantaf15531c2011-12-22 23:00:40 -0800971 *
972 * @param out Writer to use for writing JSON content
973 */
974 public JsonGenerator createJsonGenerator(Writer out)
975 throws IOException
976 {
977 IOContext ctxt = _createContext(out, false);
978 // [JACKSON-512]: allow wrapping with _outputDecorator
979 if (_outputDecorator != null) {
980 out = _outputDecorator.decorate(ctxt, out);
981 }
Tatu Salorantaeeb2fbd2012-05-28 22:00:08 -0700982 return _createGenerator(out, ctxt);
Tatu Salorantaf15531c2011-12-22 23:00:40 -0800983 }
984
985 /**
986 * Convenience method for constructing generator that uses default
987 * encoding of the format (UTF-8 for JSON and most other data formats).
988 *<p>
989 * Note: there are formats that use fixed encoding (like most binary data formats).
Tatu Salorantafeaabd12012-07-22 23:03:41 -0700990 *<p>
991 * NOTE: starting with 2.1, should not be used (will be deprecated in 2.2);
992 * instead, should call <code>createGenerator</code>.
Tatu Salorantaf15531c2011-12-22 23:00:40 -0800993 */
994 public JsonGenerator createJsonGenerator(OutputStream out) throws IOException {
995 return createJsonGenerator(out, JsonEncoding.UTF8);
996 }
997
998 /**
999 * Method for constructing JSON generator for writing JSON content
1000 * to specified file, overwriting contents it might have (or creating
1001 * it if such file does not yet exist).
1002 * Encoding to use must be specified, and needs to be one of available
1003 * types (as per JSON specification).
1004 *<p>
1005 * Underlying stream <b>is owned</b> by the generator constructed,
1006 * i.e. generator will handle closing of file when
1007 * {@link JsonGenerator#close} is called.
Tatu Salorantafeaabd12012-07-22 23:03:41 -07001008 *<p>
1009 * NOTE: starting with 2.1, should not be used (will be deprecated in 2.2);
1010 * instead, should call <code>createGenerator</code>.
Tatu Salorantaf15531c2011-12-22 23:00:40 -08001011 *
1012 * @param f File to write contents to
1013 * @param enc Character encoding to use
1014 */
1015 public JsonGenerator createJsonGenerator(File f, JsonEncoding enc)
1016 throws IOException
1017 {
1018 OutputStream out = new FileOutputStream(f);
1019 // true -> yes, we have to manage the stream since we created it
1020 IOContext ctxt = _createContext(out, true);
1021 ctxt.setEncoding(enc);
1022 if (enc == JsonEncoding.UTF8) {
1023 // [JACKSON-512]: allow wrapping with _outputDecorator
1024 if (_outputDecorator != null) {
1025 out = _outputDecorator.decorate(ctxt, out);
1026 }
1027 return _createUTF8JsonGenerator(out, ctxt);
1028 }
1029 Writer w = _createWriter(out, enc, ctxt);
1030 // [JACKSON-512]: allow wrapping with _outputDecorator
1031 if (_outputDecorator != null) {
1032 w = _outputDecorator.decorate(ctxt, w);
1033 }
Tatu Salorantaeeb2fbd2012-05-28 22:00:08 -07001034 return _createGenerator(w, ctxt);
Tatu Salorantaf15531c2011-12-22 23:00:40 -08001035 }
1036
1037 /*
1038 /**********************************************************
1039 /* Factory methods used by factory for creating parser instances,
1040 /* overridable by sub-classes
1041 /**********************************************************
1042 */
1043
1044 /**
1045 * Overridable factory method that actually instantiates desired parser
1046 * given {@link InputStream} and context object.
1047 *<p>
1048 * This method is specifically designed to remain
1049 * compatible between minor versions so that sub-classes can count
1050 * on it being called as expected. That is, it is part of official
1051 * interface from sub-class perspective, although not a public
1052 * method available to users of factory implementations.
Tatu Salorantaeeb2fbd2012-05-28 22:00:08 -07001053 *
1054 * @since 2.1
Tatu Salorantaf15531c2011-12-22 23:00:40 -08001055 */
Tatu Salorantaeeb2fbd2012-05-28 22:00:08 -07001056 protected JsonParser _createParser(InputStream in, IOContext ctxt)
Tatu Salorantaf15531c2011-12-22 23:00:40 -08001057 throws IOException, JsonParseException
1058 {
Tatu Salorantaeeb2fbd2012-05-28 22:00:08 -07001059 /* NOTE: MUST call the deprecated method until it is deleted, just so
1060 * that override still works as expected, for now.
1061 */
1062 return _createJsonParser(in, ctxt);
1063 }
1064
1065 /**
1066 * @deprecated since 2.1 -- use {@link #_createParser(InputStream, IOContext)} instead
1067 */
1068 @Deprecated
1069 protected JsonParser _createJsonParser(InputStream in, IOContext ctxt) throws IOException, JsonParseException {
Tatu07351902012-01-19 13:12:13 -08001070 // As per [JACKSON-259], may want to fully disable canonicalization:
Tatu Salorantaf15531c2011-12-22 23:00:40 -08001071 return new ByteSourceJsonBootstrapper(ctxt, in).constructParser(_parserFeatures,
Tatu07351902012-01-19 13:12:13 -08001072 _objectCodec, _rootByteSymbols, _rootCharSymbols,
1073 isEnabled(JsonFactory.Feature.CANONICALIZE_FIELD_NAMES),
1074 isEnabled(JsonFactory.Feature.INTERN_FIELD_NAMES));
Tatu Salorantaf15531c2011-12-22 23:00:40 -08001075 }
Tatu Salorantaeeb2fbd2012-05-28 22:00:08 -07001076
Tatu Salorantaf15531c2011-12-22 23:00:40 -08001077 /**
1078 * Overridable factory method that actually instantiates parser
1079 * using given {@link Reader} object for reading content.
1080 *<p>
1081 * This method is specifically designed to remain
1082 * compatible between minor versions so that sub-classes can count
1083 * on it being called as expected. That is, it is part of official
1084 * interface from sub-class perspective, although not a public
1085 * method available to users of factory implementations.
Tatu Salorantaeeb2fbd2012-05-28 22:00:08 -07001086 *
1087 * @since 2.1
Tatu Salorantaf15531c2011-12-22 23:00:40 -08001088 */
Tatu Salorantaeeb2fbd2012-05-28 22:00:08 -07001089 protected JsonParser _createParser(Reader r, IOContext ctxt)
1090 throws IOException, JsonParseException
Tatu Salorantaf15531c2011-12-22 23:00:40 -08001091 {
Tatu Salorantaeeb2fbd2012-05-28 22:00:08 -07001092 /* NOTE: MUST call the deprecated method until it is deleted, just so
1093 * that override still works as expected, for now.
1094 */
1095 return _createJsonParser(r, ctxt);
1096 }
1097
1098 /**
1099 * @deprecated since 2.1 -- use {@link #_createParser(Reader, IOContext)} instead
1100 */
1101 @Deprecated
1102 protected JsonParser _createJsonParser(Reader r, IOContext ctxt) throws IOException, JsonParseException {
Tatu Salorantaf15531c2011-12-22 23:00:40 -08001103 return new ReaderBasedJsonParser(ctxt, _parserFeatures, r, _objectCodec,
Tatu07351902012-01-19 13:12:13 -08001104 _rootCharSymbols.makeChild(isEnabled(JsonFactory.Feature.CANONICALIZE_FIELD_NAMES),
1105 isEnabled(JsonFactory.Feature.INTERN_FIELD_NAMES)));
Tatu Salorantaf15531c2011-12-22 23:00:40 -08001106 }
1107
1108 /**
1109 * Overridable factory method that actually instantiates parser
1110 * using given {@link Reader} object for reading content
1111 * passed as raw byte array.
1112 *<p>
1113 * This method is specifically designed to remain
1114 * compatible between minor versions so that sub-classes can count
1115 * on it being called as expected. That is, it is part of official
1116 * interface from sub-class perspective, although not a public
1117 * method available to users of factory implementations.
1118 */
Tatu Salorantaeeb2fbd2012-05-28 22:00:08 -07001119 protected JsonParser _createParser(byte[] data, int offset, int len, IOContext ctxt)
Tatu Salorantaf15531c2011-12-22 23:00:40 -08001120 throws IOException, JsonParseException
1121 {
Tatu Salorantaeeb2fbd2012-05-28 22:00:08 -07001122 /* NOTE: MUST call the deprecated method until it is deleted, just so
1123 * that override still works as expected, for now.
1124 */
1125 return _createJsonParser(data, offset, len, ctxt);
1126 }
1127
1128 /**
1129 * @deprecated since 2.1 -- use {@link #_createParser(byte[], int, int, IOContext)} instead
1130 */
1131 @Deprecated
1132 protected JsonParser _createJsonParser(byte[] data, int offset, int len, IOContext ctxt) throws IOException, JsonParseException {
Tatu Salorantaf15531c2011-12-22 23:00:40 -08001133 return new ByteSourceJsonBootstrapper(ctxt, data, offset, len).constructParser(_parserFeatures,
Tatu07351902012-01-19 13:12:13 -08001134 _objectCodec, _rootByteSymbols, _rootCharSymbols,
1135 isEnabled(JsonFactory.Feature.CANONICALIZE_FIELD_NAMES),
1136 isEnabled(JsonFactory.Feature.INTERN_FIELD_NAMES));
Tatu Salorantaf15531c2011-12-22 23:00:40 -08001137 }
Tatu Salorantaeeb2fbd2012-05-28 22:00:08 -07001138
Tatu Salorantaf15531c2011-12-22 23:00:40 -08001139 /*
1140 /**********************************************************
1141 /* Factory methods used by factory for creating generator instances,
1142 /* overridable by sub-classes
1143 /**********************************************************
1144 */
1145
1146 /**
1147 * Overridable factory method that actually instantiates generator for
1148 * given {@link Writer} and context object.
1149 *<p>
1150 * This method is specifically designed to remain
1151 * compatible between minor versions so that sub-classes can count
1152 * on it being called as expected. That is, it is part of official
1153 * interface from sub-class perspective, although not a public
1154 * method available to users of factory implementations.
1155 */
Tatu Salorantaeeb2fbd2012-05-28 22:00:08 -07001156 protected JsonGenerator _createGenerator(Writer out, IOContext ctxt)
1157 throws IOException
1158 {
1159 /* NOTE: MUST call the deprecated method until it is deleted, just so
1160 * that override still works as expected, for now.
1161 */
1162 return _createJsonGenerator(out, ctxt);
1163 }
1164
1165 /**
Tatu Salorantaec300272012-06-28 15:08:51 -07001166 * @deprecated since 2.1 -- use {@link #_createGenerator(Writer, IOContext)} instead
Tatu Salorantaeeb2fbd2012-05-28 22:00:08 -07001167 */
1168 @Deprecated
Tatu Salorantaf15531c2011-12-22 23:00:40 -08001169 protected JsonGenerator _createJsonGenerator(Writer out, IOContext ctxt)
1170 throws IOException
1171 {
1172 WriterBasedJsonGenerator gen = new WriterBasedJsonGenerator(ctxt, _generatorFeatures, _objectCodec, out);
1173 if (_characterEscapes != null) {
1174 gen.setCharacterEscapes(_characterEscapes);
1175 }
1176 return gen;
1177 }
1178
1179 /**
1180 * Overridable factory method that actually instantiates generator for
1181 * given {@link OutputStream} and context object, using UTF-8 encoding.
1182 *<p>
1183 * This method is specifically designed to remain
1184 * compatible between minor versions so that sub-classes can count
1185 * on it being called as expected. That is, it is part of official
1186 * interface from sub-class perspective, although not a public
1187 * method available to users of factory implementations.
1188 */
Tatu Salorantaeeb2fbd2012-05-28 22:00:08 -07001189 protected JsonGenerator _createUTF8Generator(OutputStream out, IOContext ctxt) throws IOException {
1190 return _createUTF8JsonGenerator(out, ctxt);
1191 }
1192
1193 /**
Tatu Salorantaec300272012-06-28 15:08:51 -07001194 * @deprecated since 2.1
Tatu Salorantaeeb2fbd2012-05-28 22:00:08 -07001195 */
1196 @Deprecated
Tatu Salorantaf15531c2011-12-22 23:00:40 -08001197 protected JsonGenerator _createUTF8JsonGenerator(OutputStream out, IOContext ctxt)
1198 throws IOException
1199 {
1200 UTF8JsonGenerator gen = new UTF8JsonGenerator(ctxt, _generatorFeatures, _objectCodec, out);
1201 if (_characterEscapes != null) {
1202 gen.setCharacterEscapes(_characterEscapes);
1203 }
1204 return gen;
1205 }
1206
1207 protected Writer _createWriter(OutputStream out, JsonEncoding enc, IOContext ctxt) throws IOException
1208 {
1209 // note: this should not get called any more (caller checks, dispatches)
1210 if (enc == JsonEncoding.UTF8) { // We have optimized writer for UTF-8
1211 return new UTF8Writer(ctxt, out);
1212 }
1213 // not optimal, but should do unless we really care about UTF-16/32 encoding speed
1214 return new OutputStreamWriter(out, enc.getJavaName());
1215 }
1216
1217 /*
1218 /**********************************************************
1219 /* Internal factory methods, other
1220 /**********************************************************
1221 */
1222
1223 /**
1224 * Overridable factory method that actually instantiates desired
1225 * context object.
1226 */
1227 protected IOContext _createContext(Object srcRef, boolean resourceManaged)
1228 {
1229 return new IOContext(_getBufferRecycler(), srcRef, resourceManaged);
1230 }
1231
1232 /**
1233 * Method used by factory to create buffer recycler instances
1234 * for parsers and generators.
1235 *<p>
1236 * Note: only public to give access for <code>ObjectMapper</code>
1237 */
1238 public BufferRecycler _getBufferRecycler()
1239 {
1240 SoftReference<BufferRecycler> ref = _recyclerRef.get();
1241 BufferRecycler br = (ref == null) ? null : ref.get();
1242
1243 if (br == null) {
1244 br = new BufferRecycler();
1245 _recyclerRef.set(new SoftReference<BufferRecycler>(br));
1246 }
1247 return br;
1248 }
1249
1250 /**
1251 * Helper methods used for constructing an optimal stream for
1252 * parsers to use, when input is to be read from an URL.
1253 * This helps when reading file content via URL.
1254 */
1255 protected InputStream _optimizedStreamFromURL(URL url)
1256 throws IOException
1257 {
1258 if ("file".equals(url.getProtocol())) {
1259 /* Can not do this if the path refers
1260 * to a network drive on windows. This fixes the problem;
1261 * might not be needed on all platforms (NFS?), but should not
1262 * matter a lot: performance penalty of extra wrapping is more
1263 * relevant when accessing local file system.
1264 */
1265 String host = url.getHost();
1266 if (host == null || host.length() == 0) {
1267 return new FileInputStream(url.getPath());
1268 }
1269 }
1270 return url.openStream();
1271 }
1272}