blob: 729aad22d2c8fdd64b351372f2b0e2807acb09e1 [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
Tatu Saloranta378ecdc2012-08-04 16:27:27 -0700241 /**
242 * Method for constructing a new {@link JsonFactory} that has
243 * the same settings as this instance, but is otherwise
244 * independent (i.e. nothing is actually shared, symbol tables
245 * are separate).
246 * Note that {@link ObjectCodec} reference is not copied but is
247 * set to null; caller typically needs to set it after calling
248 * this method.
249 *
250 * @since 2.1
251 */
252 public JsonFactory copy()
253 {
254 _checkInvalidCopy(JsonFactory.class);
255 return new JsonFactory(null);
256 }
257
258 /**
259 * @since 2.1
260 * @param exp
261 */
262 protected void _checkInvalidCopy(Class<?> exp)
263 {
264 if (getClass() != exp) {
265 throw new IllegalStateException("Failed copy(): "+getClass().getName()
266 +" (version: "+version()+") does not override copy(); it has to");
267 }
268 }
269
Tatu Salorantaf15531c2011-12-22 23:00:40 -0800270 /*
271 /**********************************************************
272 /* Format detection functionality (since 1.8)
273 /**********************************************************
274 */
275
276 /**
Tatu Saloranta1bdf0262012-08-24 14:43:17 -0700277 * Method that can be used to quickly check whether given schema
278 * is something that parsers and/or generators constructed by this
279 * factory could use. Note that this means possible use, at the level
280 * of data format (i.e. schema is for same data format as parsers and
281 * generators this factory constructs); individual schema instances
282 * may have further usage restrictions.
283 *
284 * @since 2.1
285 */
286 public boolean canUseSchema(FormatSchema schema) {
287 String ourFormat = getFormatName();
288 return (ourFormat != null) && ourFormat.equals(schema.getSchemaType());
289 }
290
291 /**
Tatu Salorantaf15531c2011-12-22 23:00:40 -0800292 * Method that returns short textual id identifying format
293 * this factory supports.
294 *<p>
295 * Note: sub-classes should override this method; default
296 * implementation will return null for all sub-classes
297 */
298 public String getFormatName()
299 {
300 /* Somewhat nasty check: since we can't make this abstract
301 * (due to backwards compatibility concerns), need to prevent
302 * format name "leakage"
303 */
304 if (getClass() == JsonFactory.class) {
305 return FORMAT_NAME_JSON;
306 }
307 return null;
308 }
309
310 public MatchStrength hasFormat(InputAccessor acc) throws IOException
311 {
312 // since we can't keep this abstract, only implement for "vanilla" instance
313 if (getClass() == JsonFactory.class) {
314 return hasJSONFormat(acc);
315 }
316 return null;
317 }
318
Tatu Salorantaad2df5f2012-08-22 20:55:49 -0700319 /**
320 * Method that can be called to determine if a custom
321 * {@link ObjectCodec} is needed for binding data parsed
322 * using {@link JsonParser} constructed by this factory
323 * (which typically also implies the same for serialization
324 * with {@link JsonGenerator}).
325 *
326 * @return True if custom codec is needed with parsers and
327 * generators created by this factory; false if a general
328 * {@link ObjectCodec} is enough
329 *
330 * @since 2.1
331 */
332 public boolean requiresCustomCodec() {
333 return false;
334 }
335
336 /**
337 * Helper method that can be called to determine if content accessed
338 * using given accessor seems to be JSON content.
339 */
Tatu Salorantaf15531c2011-12-22 23:00:40 -0800340 protected MatchStrength hasJSONFormat(InputAccessor acc) throws IOException
341 {
342 return ByteSourceJsonBootstrapper.hasJSONFormat(acc);
Tatu Salorantaad2df5f2012-08-22 20:55:49 -0700343 }
344
Tatu Salorantaf15531c2011-12-22 23:00:40 -0800345 /*
346 /**********************************************************
347 /* Versioned
348 /**********************************************************
349 */
350
Tatu Salorantae9b48512012-04-17 10:22:07 -0700351// @Override
Tatu Salorantaf15531c2011-12-22 23:00:40 -0800352 public Version version() {
Tatu Saloranta5a1bd992011-12-28 23:18:23 -0800353 return CoreVersion.instance.version();
Tatu Salorantaf15531c2011-12-22 23:00:40 -0800354 }
355
356 /*
357 /**********************************************************
Tatu07351902012-01-19 13:12:13 -0800358 /* Configuration, factory features
Tatu Salorantaf15531c2011-12-22 23:00:40 -0800359 /**********************************************************
360 */
361
362 /**
363 * Method for enabling or disabling specified parser feature
364 * (check {@link JsonParser.Feature} for list of features)
365 */
Tatu07351902012-01-19 13:12:13 -0800366 public final JsonFactory configure(JsonFactory.Feature f, boolean state) {
367 return state ? enable(f) : disable(f);
368 }
369
370 /**
371 * Method for enabling specified parser feature
372 * (check {@link JsonFactory.Feature} for list of features)
373 */
374 public JsonFactory enable(JsonFactory.Feature f) {
375 _factoryFeatures |= f.getMask();
Tatu Salorantaf15531c2011-12-22 23:00:40 -0800376 return this;
377 }
378
379 /**
Tatu07351902012-01-19 13:12:13 -0800380 * Method for disabling specified parser features
381 * (check {@link JsonFactory.Feature} for list of features)
382 */
383 public JsonFactory disable(JsonFactory.Feature f) {
384 _factoryFeatures &= ~f.getMask();
385 return this;
386 }
387
388 /**
389 * Checked whether specified parser feature is enabled.
390 */
391 public final boolean isEnabled(JsonFactory.Feature f) {
392 return (_factoryFeatures & f.getMask()) != 0;
393 }
394
395 /*
396 /**********************************************************
397 /* Configuration, parser configuration
398 /**********************************************************
399 */
400
401 /**
402 * Method for enabling or disabling specified parser feature
403 * (check {@link JsonParser.Feature} for list of features)
404 */
405 public final JsonFactory configure(JsonParser.Feature f, boolean state) {
406 return state ? enable(f) : disable(f);
407 }
408
409 /**
Tatu Salorantaf15531c2011-12-22 23:00:40 -0800410 * Method for enabling specified parser feature
411 * (check {@link JsonParser.Feature} for list of features)
412 */
413 public JsonFactory enable(JsonParser.Feature f) {
414 _parserFeatures |= f.getMask();
415 return this;
416 }
417
418 /**
419 * Method for disabling specified parser features
420 * (check {@link JsonParser.Feature} for list of features)
421 */
422 public JsonFactory disable(JsonParser.Feature f) {
423 _parserFeatures &= ~f.getMask();
424 return this;
425 }
426
427 /**
428 * Checked whether specified parser feature is enabled.
429 */
430 public final boolean isEnabled(JsonParser.Feature f) {
431 return (_parserFeatures & f.getMask()) != 0;
432 }
433
434 /**
435 * Method for getting currently configured input decorator (if any;
436 * there is no default decorator).
437 */
438 public InputDecorator getInputDecorator() {
439 return _inputDecorator;
440 }
441
442 /**
443 * Method for overriding currently configured input decorator
444 */
445 public JsonFactory setInputDecorator(InputDecorator d) {
446 _inputDecorator = d;
447 return this;
448 }
449
450 /*
451 /**********************************************************
452 /* Configuration, generator settings
453 /**********************************************************
454 */
455
456 /**
457 * Method for enabling or disabling specified generator feature
458 * (check {@link JsonGenerator.Feature} for list of features)
459 */
460 public final JsonFactory configure(JsonGenerator.Feature f, boolean state) {
Tatu07351902012-01-19 13:12:13 -0800461 return state ? enable(f) : disable(f);
Tatu Salorantaf15531c2011-12-22 23:00:40 -0800462 }
463
464
465 /**
466 * Method for enabling specified generator features
467 * (check {@link JsonGenerator.Feature} for list of features)
468 */
469 public JsonFactory enable(JsonGenerator.Feature f) {
470 _generatorFeatures |= f.getMask();
471 return this;
472 }
473
474 /**
475 * Method for disabling specified generator feature
476 * (check {@link JsonGenerator.Feature} for list of features)
477 */
478 public JsonFactory disable(JsonGenerator.Feature f) {
479 _generatorFeatures &= ~f.getMask();
480 return this;
481 }
482
483 /**
484 * Check whether specified generator feature is enabled.
485 */
486 public final boolean isEnabled(JsonGenerator.Feature f) {
487 return (_generatorFeatures & f.getMask()) != 0;
488 }
489
490 /**
491 * Method for accessing custom escapes factory uses for {@link JsonGenerator}s
492 * it creates.
493 */
494 public CharacterEscapes getCharacterEscapes() {
495 return _characterEscapes;
496 }
497
498 /**
499 * Method for defining custom escapes factory uses for {@link JsonGenerator}s
500 * it creates.
501 */
502 public JsonFactory setCharacterEscapes(CharacterEscapes esc) {
503 _characterEscapes = esc;
504 return this;
505 }
506
507 /**
508 * Method for getting currently configured output decorator (if any;
509 * there is no default decorator).
510 */
511 public OutputDecorator getOutputDecorator() {
512 return _outputDecorator;
513 }
514
515 /**
516 * Method for overriding currently configured output decorator
517 */
518 public JsonFactory setOutputDecorator(OutputDecorator d) {
519 _outputDecorator = d;
520 return this;
521 }
522
523 /*
524 /**********************************************************
525 /* Configuration, other
526 /**********************************************************
527 */
528
529 /**
530 * Method for associating a {@link ObjectCodec} (typically
Tatu Salorantad77350e2011-12-22 23:13:13 -0800531 * a <code>com.fasterxml.jackson.databind.ObjectMapper</code>)
532 * with this factory (and more importantly, parsers and generators
Tatu Salorantaf15531c2011-12-22 23:00:40 -0800533 * it constructs). This is needed to use data-binding methods
534 * of {@link JsonParser} and {@link JsonGenerator} instances.
535 */
536 public JsonFactory setCodec(ObjectCodec oc) {
537 _objectCodec = oc;
538 return this;
539 }
540
541 public ObjectCodec getCodec() { return _objectCodec; }
542
543 /*
544 /**********************************************************
Tatu Salorantafeaabd12012-07-22 23:03:41 -0700545 /* Parser factories (new ones, as per [Issue-25])
Tatu Salorantaf15531c2011-12-22 23:00:40 -0800546 /**********************************************************
547 */
548
549 /**
550 * Method for constructing JSON parser instance to parse
551 * contents of specified file. Encoding is auto-detected
552 * from contents according to JSON specification recommended
553 * mechanism.
554 *<p>
555 * Underlying input stream (needed for reading contents)
556 * will be <b>owned</b> (and managed, i.e. closed as need be) by
557 * the parser, since caller has no access to it.
558 *
559 * @param f File that contains JSON content to parse
Tatu Salorantafeaabd12012-07-22 23:03:41 -0700560 *
561 * @since 2.1
562 */
563 public JsonParser createParser(File f)
564 throws IOException, JsonParseException
565 {
566 // Must delegate to old version, until 2.2
567 // TODO: change direction in 2.2; after ensuring impls support new method
568 return createJsonParser(f);
569 }
570
571 /**
572 * Method for constructing JSON parser instance to parse
573 * contents of resource reference by given URL.
574 * Encoding is auto-detected
575 * from contents according to JSON specification recommended
576 * mechanism.
577 *<p>
578 * Underlying input stream (needed for reading contents)
579 * will be <b>owned</b> (and managed, i.e. closed as need be) by
580 * the parser, since caller has no access to it.
581 *
582 * @param url URL pointing to resource that contains JSON content to parse
583 *
584 * @since 2.1
585 */
586 public JsonParser createParser(URL url)
587 throws IOException, JsonParseException
588 {
589 // Must delegate to old version, until 2.2
590 // TODO: change direction in 2.2; after ensuring impls support new method
591 return createJsonParser(url);
592 }
593
594 /**
595 * Method for constructing JSON parser instance to parse
596 * the contents accessed via specified input stream.
597 *<p>
598 * The input stream will <b>not be owned</b> by
599 * the parser, it will still be managed (i.e. closed if
600 * end-of-stream is reacher, or parser close method called)
601 * if (and only if) {@link com.fasterxml.jackson.core.JsonParser.Feature#AUTO_CLOSE_SOURCE}
602 * is enabled.
603 *<p>
604 * Note: no encoding argument is taken since it can always be
605 * auto-detected as suggested by JSON RFC.
606 *
607 * @param in InputStream to use for reading JSON content to parse
608 *
609 * @since 2.1
610 */
611 public JsonParser createParser(InputStream in)
612 throws IOException, JsonParseException
613 {
614 // Must delegate to old version, until 2.2
615 // TODO: change direction in 2.2; after ensuring impls support new method
616 return createJsonParser(in);
617 }
618
619 /**
620 * Method for constructing parser for parsing
621 * the contents accessed via specified Reader.
622 <p>
623 * The read stream will <b>not be owned</b> by
624 * the parser, it will still be managed (i.e. closed if
625 * end-of-stream is reacher, or parser close method called)
626 * if (and only if) {@link com.fasterxml.jackson.core.JsonParser.Feature#AUTO_CLOSE_SOURCE}
627 * is enabled.
628 *
629 * @param r Reader to use for reading JSON content to parse
630 *
631 * @since 2.1
632 */
633 public JsonParser createParser(Reader r)
634 throws IOException, JsonParseException
635 {
636 // Must delegate to old version, until 2.2
637 // TODO: change direction in 2.2; after ensuring impls support new method
638 return createJsonParser(r);
639 }
640
641 /**
642 * Method for constructing parser for parsing
643 * the contents of given byte array.
644 *
645 * @since 2.1
646 */
647 public JsonParser createParser(byte[] data)
648 throws IOException, JsonParseException
649 {
650 // Must delegate to old version, until 2.2
651 // TODO: change direction in 2.2; after ensuring impls support new method
652 return createJsonParser(data);
653 }
654
655 /**
656 * Method for constructing parser for parsing
657 * the contents of given byte array.
658 *
659 * @param data Buffer that contains data to parse
660 * @param offset Offset of the first data byte within buffer
661 * @param len Length of contents to parse within buffer
662 *
663 * @since 2.1
664 */
665 public JsonParser createParser(byte[] data, int offset, int len)
666 throws IOException, JsonParseException
667 {
668 // Must delegate to old version, until 2.2
669 // TODO: change direction in 2.2; after ensuring impls support new method
670 return createJsonParser(data, offset, len);
671 }
672
673 /**
674 * Method for constructing parser for parsing
675 * contents of given String.
676 *
677 * @since 2.1
678 */
679 public JsonParser createParser(String content)
680 throws IOException, JsonParseException
681 {
682 // Must delegate to old version, until 2.2
683 // TODO: change direction in 2.2; after ensuring impls support new method
684 return createJsonParser(content);
685 }
686
687 /*
688 /**********************************************************
689 /* Parser factories (old ones, as per [Issue-25])
690 /**********************************************************
691 */
692
693 /**
694 * Method for constructing JSON parser instance to parse
695 * contents of specified file. Encoding is auto-detected
696 * from contents according to JSON specification recommended
697 * mechanism.
698 *<p>
699 * Underlying input stream (needed for reading contents)
700 * will be <b>owned</b> (and managed, i.e. closed as need be) by
701 * the parser, since caller has no access to it.
702 *<p>
703 * NOTE: as of 2.1, should not be used (will be deprecated in 2.2);
704 * instead, should call <code>createParser</code>.
705 *
706 * @param f File that contains JSON content to parse
Tatu Salorantaf15531c2011-12-22 23:00:40 -0800707 */
708 public JsonParser createJsonParser(File f)
709 throws IOException, JsonParseException
710 {
711 // true, since we create InputStream from File
712 IOContext ctxt = _createContext(f, true);
713 InputStream in = new FileInputStream(f);
714 // [JACKSON-512]: allow wrapping with InputDecorator
715 if (_inputDecorator != null) {
716 in = _inputDecorator.decorate(ctxt, in);
717 }
Tatu Salorantaeeb2fbd2012-05-28 22:00:08 -0700718 return _createParser(in, ctxt);
Tatu Salorantaf15531c2011-12-22 23:00:40 -0800719 }
720
721 /**
722 * Method for constructing JSON parser instance to parse
723 * contents of resource reference by given URL.
724 * Encoding is auto-detected
725 * from contents according to JSON specification recommended
726 * mechanism.
727 *<p>
728 * Underlying input stream (needed for reading contents)
729 * will be <b>owned</b> (and managed, i.e. closed as need be) by
730 * the parser, since caller has no access to it.
Tatu Salorantafeaabd12012-07-22 23:03:41 -0700731 *<p>
732 * NOTE: as of 2.1, should not be used (will be deprecated in 2.2);
733 * instead, should call <code>createParser</code>.
Tatu Salorantaf15531c2011-12-22 23:00:40 -0800734 *
735 * @param url URL pointing to resource that contains JSON content to parse
736 */
737 public JsonParser createJsonParser(URL url)
738 throws IOException, JsonParseException
739 {
740 // true, since we create InputStream from URL
741 IOContext ctxt = _createContext(url, true);
742 InputStream in = _optimizedStreamFromURL(url);
743 // [JACKSON-512]: allow wrapping with InputDecorator
744 if (_inputDecorator != null) {
745 in = _inputDecorator.decorate(ctxt, in);
746 }
Tatu Salorantaeeb2fbd2012-05-28 22:00:08 -0700747 return _createParser(in, ctxt);
Tatu Salorantaf15531c2011-12-22 23:00:40 -0800748 }
749
750 /**
751 * Method for constructing JSON parser instance to parse
752 * the contents accessed via specified input stream.
753 *<p>
754 * The input stream will <b>not be owned</b> by
755 * the parser, it will still be managed (i.e. closed if
756 * end-of-stream is reacher, or parser close method called)
757 * if (and only if) {@link com.fasterxml.jackson.core.JsonParser.Feature#AUTO_CLOSE_SOURCE}
758 * is enabled.
759 *<p>
760 * Note: no encoding argument is taken since it can always be
Tatu Salorantafeaabd12012-07-22 23:03:41 -0700761 * auto-detected as suggested by JSON RFC.
762 *<p>
763 * NOTE: as of 2.1, should not be used (will be deprecated in 2.2);
764 * instead, should call <code>createParser</code>.
Tatu Salorantaf15531c2011-12-22 23:00:40 -0800765 *
766 * @param in InputStream to use for reading JSON content to parse
767 */
768 public JsonParser createJsonParser(InputStream in)
769 throws IOException, JsonParseException
770 {
771 IOContext ctxt = _createContext(in, false);
772 // [JACKSON-512]: allow wrapping with InputDecorator
773 if (_inputDecorator != null) {
774 in = _inputDecorator.decorate(ctxt, in);
775 }
Tatu Salorantaeeb2fbd2012-05-28 22:00:08 -0700776 return _createParser(in, ctxt);
Tatu Salorantaf15531c2011-12-22 23:00:40 -0800777 }
778
779 /**
780 * Method for constructing parser for parsing
781 * the contents accessed via specified Reader.
782 <p>
783 * The read stream will <b>not be owned</b> by
784 * the parser, it will still be managed (i.e. closed if
785 * end-of-stream is reacher, or parser close method called)
786 * if (and only if) {@link com.fasterxml.jackson.core.JsonParser.Feature#AUTO_CLOSE_SOURCE}
787 * is enabled.
788 *<p>
Tatu Salorantafeaabd12012-07-22 23:03:41 -0700789 * NOTE: as of 2.1, should not be used (will be deprecated in 2.2);
790 * instead, should call <code>createParser</code>.
Tatu Salorantaf15531c2011-12-22 23:00:40 -0800791 *
792 * @param r Reader to use for reading JSON content to parse
793 */
794 public JsonParser createJsonParser(Reader r)
795 throws IOException, JsonParseException
796 {
797 // false -> we do NOT own Reader (did not create it)
798 IOContext ctxt = _createContext(r, false);
799 // [JACKSON-512]: allow wrapping with InputDecorator
800 if (_inputDecorator != null) {
801 r = _inputDecorator.decorate(ctxt, r);
802 }
Tatu Saloranta3e5ff6d2012-06-27 18:46:43 -0700803 return _createParser(r, ctxt);
Tatu Salorantaf15531c2011-12-22 23:00:40 -0800804 }
805
806 /**
807 * Method for constructing parser for parsing
808 * the contents of given byte array.
Tatu Salorantafeaabd12012-07-22 23:03:41 -0700809 *<p>
810 * NOTE: as of 2.1, should not be used (will be deprecated in 2.2);
811 * instead, should call <code>createParser</code>.
Tatu Salorantaf15531c2011-12-22 23:00:40 -0800812 */
813 public JsonParser createJsonParser(byte[] data)
814 throws IOException, JsonParseException
815 {
816 IOContext ctxt = _createContext(data, true);
817 // [JACKSON-512]: allow wrapping with InputDecorator
818 if (_inputDecorator != null) {
819 InputStream in = _inputDecorator.decorate(ctxt, data, 0, data.length);
820 if (in != null) {
Tatu Salorantaeeb2fbd2012-05-28 22:00:08 -0700821 return _createParser(in, ctxt);
Tatu Salorantaf15531c2011-12-22 23:00:40 -0800822 }
823 }
Tatu Salorantaeeb2fbd2012-05-28 22:00:08 -0700824 return _createParser(data, 0, data.length, ctxt);
Tatu Salorantaf15531c2011-12-22 23:00:40 -0800825 }
826
827 /**
828 * Method for constructing parser for parsing
829 * the contents of given byte array.
Tatu Salorantafeaabd12012-07-22 23:03:41 -0700830 *<p>
831 * NOTE: as of 2.1, should not be used (will be deprecated in 2.2);
832 * instead, should call <code>createParser</code>.
Tatu Salorantaf15531c2011-12-22 23:00:40 -0800833 *
834 * @param data Buffer that contains data to parse
835 * @param offset Offset of the first data byte within buffer
836 * @param len Length of contents to parse within buffer
837 */
838 public JsonParser createJsonParser(byte[] data, int offset, int len)
839 throws IOException, JsonParseException
840 {
841 IOContext ctxt = _createContext(data, true);
842 // [JACKSON-512]: allow wrapping with InputDecorator
843 if (_inputDecorator != null) {
844 InputStream in = _inputDecorator.decorate(ctxt, data, offset, len);
845 if (in != null) {
Tatu Salorantaeeb2fbd2012-05-28 22:00:08 -0700846 return _createParser(in, ctxt);
Tatu Salorantaf15531c2011-12-22 23:00:40 -0800847 }
848 }
Tatu Salorantaeeb2fbd2012-05-28 22:00:08 -0700849 return _createParser(data, offset, len, ctxt);
Tatu Salorantaf15531c2011-12-22 23:00:40 -0800850 }
851
852 /**
853 * Method for constructing parser for parsing
854 * contents of given String.
Tatu Salorantafeaabd12012-07-22 23:03:41 -0700855 *<p>
856 * NOTE: as of 2.1, should not be used (will be deprecated in 2.2);
857 * instead, should call <code>createParser</code>.
Tatu Salorantaf15531c2011-12-22 23:00:40 -0800858 */
859 public JsonParser createJsonParser(String content)
860 throws IOException, JsonParseException
861 {
Tatu Saloranta3e5ff6d2012-06-27 18:46:43 -0700862 Reader r = new StringReader(content);
Tatu Salorantaf15531c2011-12-22 23:00:40 -0800863 // true -> we own the Reader (and must close); not a big deal
864 IOContext ctxt = _createContext(r, true);
865 // [JACKSON-512]: allow wrapping with InputDecorator
866 if (_inputDecorator != null) {
867 r = _inputDecorator.decorate(ctxt, r);
868 }
Tatu Saloranta3e5ff6d2012-06-27 18:46:43 -0700869 return _createParser(r, ctxt);
Tatu Salorantaf15531c2011-12-22 23:00:40 -0800870 }
871
872 /*
873 /**********************************************************
Tatu Salorantafeaabd12012-07-22 23:03:41 -0700874 /* Generator factories, new (as per [Issue-25]
Tatu Salorantaf15531c2011-12-22 23:00:40 -0800875 /**********************************************************
876 */
877
878 /**
879 * Method for constructing JSON generator for writing JSON content
880 * using specified output stream.
881 * Encoding to use must be specified, and needs to be one of available
882 * types (as per JSON specification).
883 *<p>
884 * Underlying stream <b>is NOT owned</b> by the generator constructed,
885 * so that generator will NOT close the output stream when
886 * {@link JsonGenerator#close} is called (unless auto-closing
887 * feature,
888 * {@link com.fasterxml.jackson.core.JsonGenerator.Feature#AUTO_CLOSE_TARGET}
889 * is enabled).
890 * Using application needs to close it explicitly if this is the case.
891 *<p>
892 * Note: there are formats that use fixed encoding (like most binary data formats)
893 * and that ignore passed in encoding.
Tatu Salorantafeaabd12012-07-22 23:03:41 -0700894 *<p>
895 * NOTE: starting with 2.1, should not be used (will be deprecated in 2.2);
896 * instead, should call <code>createGenerator</code>.
897 *
898 * @since 2.1 Will eventually replace <code>createJsonGenerator</code> variant.
899 *
900 * @param out OutputStream to use for writing JSON content
901 * @param enc Character encoding to use
902 */
903 public JsonGenerator createGenerator(OutputStream out, JsonEncoding enc)
904 throws IOException
905 {
906 return createJsonGenerator(out, enc);
907 }
908
909 /**
910 * Method for constructing JSON generator for writing JSON content
911 * using specified Writer.
912 *<p>
913 * Underlying stream <b>is NOT owned</b> by the generator constructed,
914 * so that generator will NOT close the Reader when
915 * {@link JsonGenerator#close} is called (unless auto-closing
916 * feature,
917 * {@link com.fasterxml.jackson.core.JsonGenerator.Feature#AUTO_CLOSE_TARGET} is enabled).
918 * Using application needs to close it explicitly.
919 *<p>
920 * NOTE: starting with 2.1, should not be used (will be deprecated in 2.2);
921 * instead, should call <code>createGenerator</code>.
922 *
923 * @since 2.1 Will eventually replace <code>createJsonGenerator</code> variant.
924 *
925 * @param out Writer to use for writing JSON content
926 */
927 public JsonGenerator createGenerator(Writer out)
928 throws IOException
929 {
930 return createJsonGenerator(out);
931 }
932
933 /**
934 * Convenience method for constructing generator that uses default
935 * encoding of the format (UTF-8 for JSON and most other data formats).
936 *<p>
937 * Note: there are formats that use fixed encoding (like most binary data formats).
938 *<p>
939 * NOTE: starting with 2.1, should not be used (will be deprecated in 2.2);
940 * instead, should call <code>createGenerator</code>.
941 *
942 * @since 2.1 Will eventually replace <code>createJsonGenerator</code> variant.
943 */
944 public JsonGenerator createGenerator(OutputStream out) throws IOException {
945 return createJsonGenerator(out);
946 }
947
948 /**
949 * Method for constructing JSON generator for writing JSON content
950 * to specified file, overwriting contents it might have (or creating
951 * it if such file does not yet exist).
952 * Encoding to use must be specified, and needs to be one of available
953 * types (as per JSON specification).
954 *<p>
955 * Underlying stream <b>is owned</b> by the generator constructed,
956 * i.e. generator will handle closing of file when
957 * {@link JsonGenerator#close} is called.
958 *<p>
959 * NOTE: starting with 2.1, should not be used (will be deprecated in 2.2);
960 * instead, should call <code>createGenerator</code>.
961 *
962 * @since 2.1 Will eventually replace <code>createJsonGenerator</code> variant.
963 *
964 * @param f File to write contents to
965 * @param enc Character encoding to use
966 */
967 public JsonGenerator createGenerator(File f, JsonEncoding enc)
968 throws IOException
969 {
970 return createJsonGenerator(f, enc);
971 }
972
973 /*
974 /**********************************************************
975 /* Generator factories, old (as per [Issue-25]
976 /**********************************************************
977 */
978
979 /**
980 * Method for constructing JSON generator for writing JSON content
981 * using specified output stream.
982 * Encoding to use must be specified, and needs to be one of available
983 * types (as per JSON specification).
984 *<p>
985 * Underlying stream <b>is NOT owned</b> by the generator constructed,
986 * so that generator will NOT close the output stream when
987 * {@link JsonGenerator#close} is called (unless auto-closing
988 * feature,
989 * {@link com.fasterxml.jackson.core.JsonGenerator.Feature#AUTO_CLOSE_TARGET}
990 * is enabled).
991 * Using application needs to close it explicitly if this is the case.
992 *<p>
993 * Note: there are formats that use fixed encoding (like most binary data formats)
994 * and that ignore passed in encoding.
995 *<p>
996 * NOTE: starting with 2.1, should not be used (will be deprecated in 2.2);
997 * instead, should call <code>createGenerator</code>.
Tatu Salorantaf15531c2011-12-22 23:00:40 -0800998 *
999 * @param out OutputStream to use for writing JSON content
1000 * @param enc Character encoding to use
1001 */
1002 public JsonGenerator createJsonGenerator(OutputStream out, JsonEncoding enc)
1003 throws IOException
1004 {
1005 // false -> we won't manage the stream unless explicitly directed to
1006 IOContext ctxt = _createContext(out, false);
1007 ctxt.setEncoding(enc);
1008 if (enc == JsonEncoding.UTF8) {
1009 // [JACKSON-512]: allow wrapping with _outputDecorator
1010 if (_outputDecorator != null) {
1011 out = _outputDecorator.decorate(ctxt, out);
1012 }
1013 return _createUTF8JsonGenerator(out, ctxt);
1014 }
1015 Writer w = _createWriter(out, enc, ctxt);
1016 // [JACKSON-512]: allow wrapping with _outputDecorator
1017 if (_outputDecorator != null) {
1018 w = _outputDecorator.decorate(ctxt, w);
1019 }
Tatu Salorantaeeb2fbd2012-05-28 22:00:08 -07001020 return _createGenerator(w, ctxt);
Tatu Salorantaf15531c2011-12-22 23:00:40 -08001021 }
1022
1023 /**
1024 * Method for constructing JSON generator for writing JSON content
1025 * using specified Writer.
1026 *<p>
1027 * Underlying stream <b>is NOT owned</b> by the generator constructed,
1028 * so that generator will NOT close the Reader when
1029 * {@link JsonGenerator#close} is called (unless auto-closing
1030 * feature,
1031 * {@link com.fasterxml.jackson.core.JsonGenerator.Feature#AUTO_CLOSE_TARGET} is enabled).
1032 * Using application needs to close it explicitly.
Tatu Salorantafeaabd12012-07-22 23:03:41 -07001033 *<p>
1034 * NOTE: starting with 2.1, should not be used (will be deprecated in 2.2);
1035 * instead, should call <code>createGenerator</code>.
Tatu Salorantaf15531c2011-12-22 23:00:40 -08001036 *
1037 * @param out Writer to use for writing JSON content
1038 */
1039 public JsonGenerator createJsonGenerator(Writer out)
1040 throws IOException
1041 {
1042 IOContext ctxt = _createContext(out, false);
1043 // [JACKSON-512]: allow wrapping with _outputDecorator
1044 if (_outputDecorator != null) {
1045 out = _outputDecorator.decorate(ctxt, out);
1046 }
Tatu Salorantaeeb2fbd2012-05-28 22:00:08 -07001047 return _createGenerator(out, ctxt);
Tatu Salorantaf15531c2011-12-22 23:00:40 -08001048 }
1049
1050 /**
1051 * Convenience method for constructing generator that uses default
1052 * encoding of the format (UTF-8 for JSON and most other data formats).
1053 *<p>
1054 * Note: there are formats that use fixed encoding (like most binary data formats).
Tatu Salorantafeaabd12012-07-22 23:03:41 -07001055 *<p>
1056 * NOTE: starting with 2.1, should not be used (will be deprecated in 2.2);
1057 * instead, should call <code>createGenerator</code>.
Tatu Salorantaf15531c2011-12-22 23:00:40 -08001058 */
1059 public JsonGenerator createJsonGenerator(OutputStream out) throws IOException {
1060 return createJsonGenerator(out, JsonEncoding.UTF8);
1061 }
1062
1063 /**
1064 * Method for constructing JSON generator for writing JSON content
1065 * to specified file, overwriting contents it might have (or creating
1066 * it if such file does not yet exist).
1067 * Encoding to use must be specified, and needs to be one of available
1068 * types (as per JSON specification).
1069 *<p>
1070 * Underlying stream <b>is owned</b> by the generator constructed,
1071 * i.e. generator will handle closing of file when
1072 * {@link JsonGenerator#close} is called.
Tatu Salorantafeaabd12012-07-22 23:03:41 -07001073 *<p>
1074 * NOTE: starting with 2.1, should not be used (will be deprecated in 2.2);
1075 * instead, should call <code>createGenerator</code>.
Tatu Salorantaf15531c2011-12-22 23:00:40 -08001076 *
1077 * @param f File to write contents to
1078 * @param enc Character encoding to use
1079 */
1080 public JsonGenerator createJsonGenerator(File f, JsonEncoding enc)
1081 throws IOException
1082 {
1083 OutputStream out = new FileOutputStream(f);
1084 // true -> yes, we have to manage the stream since we created it
1085 IOContext ctxt = _createContext(out, true);
1086 ctxt.setEncoding(enc);
1087 if (enc == JsonEncoding.UTF8) {
1088 // [JACKSON-512]: allow wrapping with _outputDecorator
1089 if (_outputDecorator != null) {
1090 out = _outputDecorator.decorate(ctxt, out);
1091 }
1092 return _createUTF8JsonGenerator(out, ctxt);
1093 }
1094 Writer w = _createWriter(out, enc, ctxt);
1095 // [JACKSON-512]: allow wrapping with _outputDecorator
1096 if (_outputDecorator != null) {
1097 w = _outputDecorator.decorate(ctxt, w);
1098 }
Tatu Salorantaeeb2fbd2012-05-28 22:00:08 -07001099 return _createGenerator(w, ctxt);
Tatu Salorantaf15531c2011-12-22 23:00:40 -08001100 }
1101
1102 /*
1103 /**********************************************************
1104 /* Factory methods used by factory for creating parser instances,
1105 /* overridable by sub-classes
1106 /**********************************************************
1107 */
1108
1109 /**
1110 * Overridable factory method that actually instantiates desired parser
1111 * given {@link InputStream} and context object.
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.
Tatu Salorantaeeb2fbd2012-05-28 22:00:08 -07001118 *
1119 * @since 2.1
Tatu Salorantaf15531c2011-12-22 23:00:40 -08001120 */
Tatu Salorantaeeb2fbd2012-05-28 22:00:08 -07001121 protected JsonParser _createParser(InputStream in, IOContext ctxt)
Tatu Salorantaf15531c2011-12-22 23:00:40 -08001122 throws IOException, JsonParseException
1123 {
Tatu Salorantaeeb2fbd2012-05-28 22:00:08 -07001124 /* NOTE: MUST call the deprecated method until it is deleted, just so
1125 * that override still works as expected, for now.
1126 */
1127 return _createJsonParser(in, ctxt);
1128 }
1129
1130 /**
1131 * @deprecated since 2.1 -- use {@link #_createParser(InputStream, IOContext)} instead
1132 */
1133 @Deprecated
1134 protected JsonParser _createJsonParser(InputStream in, IOContext ctxt) throws IOException, JsonParseException {
Tatu07351902012-01-19 13:12:13 -08001135 // As per [JACKSON-259], may want to fully disable canonicalization:
Tatu Salorantaf15531c2011-12-22 23:00:40 -08001136 return new ByteSourceJsonBootstrapper(ctxt, in).constructParser(_parserFeatures,
Tatu07351902012-01-19 13:12:13 -08001137 _objectCodec, _rootByteSymbols, _rootCharSymbols,
1138 isEnabled(JsonFactory.Feature.CANONICALIZE_FIELD_NAMES),
1139 isEnabled(JsonFactory.Feature.INTERN_FIELD_NAMES));
Tatu Salorantaf15531c2011-12-22 23:00:40 -08001140 }
Tatu Salorantaeeb2fbd2012-05-28 22:00:08 -07001141
Tatu Salorantaf15531c2011-12-22 23:00:40 -08001142 /**
1143 * Overridable factory method that actually instantiates parser
1144 * using given {@link Reader} object for reading content.
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(Reader r, IOContext ctxt)
1155 throws IOException, JsonParseException
Tatu Salorantaf15531c2011-12-22 23:00:40 -08001156 {
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(r, ctxt);
1161 }
1162
1163 /**
1164 * @deprecated since 2.1 -- use {@link #_createParser(Reader, IOContext)} instead
1165 */
1166 @Deprecated
1167 protected JsonParser _createJsonParser(Reader r, IOContext ctxt) throws IOException, JsonParseException {
Tatu Salorantaf15531c2011-12-22 23:00:40 -08001168 return new ReaderBasedJsonParser(ctxt, _parserFeatures, r, _objectCodec,
Tatu07351902012-01-19 13:12:13 -08001169 _rootCharSymbols.makeChild(isEnabled(JsonFactory.Feature.CANONICALIZE_FIELD_NAMES),
1170 isEnabled(JsonFactory.Feature.INTERN_FIELD_NAMES)));
Tatu Salorantaf15531c2011-12-22 23:00:40 -08001171 }
1172
1173 /**
1174 * Overridable factory method that actually instantiates parser
1175 * using given {@link Reader} object for reading content
1176 * passed as raw byte array.
1177 *<p>
1178 * This method is specifically designed to remain
1179 * compatible between minor versions so that sub-classes can count
1180 * on it being called as expected. That is, it is part of official
1181 * interface from sub-class perspective, although not a public
1182 * method available to users of factory implementations.
1183 */
Tatu Salorantaeeb2fbd2012-05-28 22:00:08 -07001184 protected JsonParser _createParser(byte[] data, int offset, int len, IOContext ctxt)
Tatu Salorantaf15531c2011-12-22 23:00:40 -08001185 throws IOException, JsonParseException
1186 {
Tatu Salorantaeeb2fbd2012-05-28 22:00:08 -07001187 /* NOTE: MUST call the deprecated method until it is deleted, just so
1188 * that override still works as expected, for now.
1189 */
1190 return _createJsonParser(data, offset, len, ctxt);
1191 }
1192
1193 /**
1194 * @deprecated since 2.1 -- use {@link #_createParser(byte[], int, int, IOContext)} instead
1195 */
1196 @Deprecated
1197 protected JsonParser _createJsonParser(byte[] data, int offset, int len, IOContext ctxt) throws IOException, JsonParseException {
Tatu Salorantaf15531c2011-12-22 23:00:40 -08001198 return new ByteSourceJsonBootstrapper(ctxt, data, offset, len).constructParser(_parserFeatures,
Tatu07351902012-01-19 13:12:13 -08001199 _objectCodec, _rootByteSymbols, _rootCharSymbols,
1200 isEnabled(JsonFactory.Feature.CANONICALIZE_FIELD_NAMES),
1201 isEnabled(JsonFactory.Feature.INTERN_FIELD_NAMES));
Tatu Salorantaf15531c2011-12-22 23:00:40 -08001202 }
Tatu Salorantaeeb2fbd2012-05-28 22:00:08 -07001203
Tatu Salorantaf15531c2011-12-22 23:00:40 -08001204 /*
1205 /**********************************************************
1206 /* Factory methods used by factory for creating generator instances,
1207 /* overridable by sub-classes
1208 /**********************************************************
1209 */
1210
1211 /**
1212 * Overridable factory method that actually instantiates generator for
1213 * given {@link Writer} and context object.
1214 *<p>
1215 * This method is specifically designed to remain
1216 * compatible between minor versions so that sub-classes can count
1217 * on it being called as expected. That is, it is part of official
1218 * interface from sub-class perspective, although not a public
1219 * method available to users of factory implementations.
1220 */
Tatu Salorantaeeb2fbd2012-05-28 22:00:08 -07001221 protected JsonGenerator _createGenerator(Writer out, IOContext ctxt)
1222 throws IOException
1223 {
1224 /* NOTE: MUST call the deprecated method until it is deleted, just so
1225 * that override still works as expected, for now.
1226 */
1227 return _createJsonGenerator(out, ctxt);
1228 }
1229
1230 /**
Tatu Salorantaec300272012-06-28 15:08:51 -07001231 * @deprecated since 2.1 -- use {@link #_createGenerator(Writer, IOContext)} instead
Tatu Salorantaeeb2fbd2012-05-28 22:00:08 -07001232 */
1233 @Deprecated
Tatu Salorantaf15531c2011-12-22 23:00:40 -08001234 protected JsonGenerator _createJsonGenerator(Writer out, IOContext ctxt)
1235 throws IOException
1236 {
1237 WriterBasedJsonGenerator gen = new WriterBasedJsonGenerator(ctxt, _generatorFeatures, _objectCodec, out);
1238 if (_characterEscapes != null) {
1239 gen.setCharacterEscapes(_characterEscapes);
1240 }
1241 return gen;
1242 }
1243
1244 /**
1245 * Overridable factory method that actually instantiates generator for
1246 * given {@link OutputStream} and context object, using UTF-8 encoding.
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 _createUTF8Generator(OutputStream out, IOContext ctxt) throws IOException {
1255 return _createUTF8JsonGenerator(out, ctxt);
1256 }
1257
1258 /**
Tatu Salorantaec300272012-06-28 15:08:51 -07001259 * @deprecated since 2.1
Tatu Salorantaeeb2fbd2012-05-28 22:00:08 -07001260 */
1261 @Deprecated
Tatu Salorantaf15531c2011-12-22 23:00:40 -08001262 protected JsonGenerator _createUTF8JsonGenerator(OutputStream out, IOContext ctxt)
1263 throws IOException
1264 {
1265 UTF8JsonGenerator gen = new UTF8JsonGenerator(ctxt, _generatorFeatures, _objectCodec, out);
1266 if (_characterEscapes != null) {
1267 gen.setCharacterEscapes(_characterEscapes);
1268 }
1269 return gen;
1270 }
1271
1272 protected Writer _createWriter(OutputStream out, JsonEncoding enc, IOContext ctxt) throws IOException
1273 {
1274 // note: this should not get called any more (caller checks, dispatches)
1275 if (enc == JsonEncoding.UTF8) { // We have optimized writer for UTF-8
1276 return new UTF8Writer(ctxt, out);
1277 }
1278 // not optimal, but should do unless we really care about UTF-16/32 encoding speed
1279 return new OutputStreamWriter(out, enc.getJavaName());
1280 }
1281
1282 /*
1283 /**********************************************************
1284 /* Internal factory methods, other
1285 /**********************************************************
1286 */
1287
1288 /**
1289 * Overridable factory method that actually instantiates desired
1290 * context object.
1291 */
1292 protected IOContext _createContext(Object srcRef, boolean resourceManaged)
1293 {
1294 return new IOContext(_getBufferRecycler(), srcRef, resourceManaged);
1295 }
1296
1297 /**
1298 * Method used by factory to create buffer recycler instances
1299 * for parsers and generators.
1300 *<p>
1301 * Note: only public to give access for <code>ObjectMapper</code>
1302 */
1303 public BufferRecycler _getBufferRecycler()
1304 {
1305 SoftReference<BufferRecycler> ref = _recyclerRef.get();
1306 BufferRecycler br = (ref == null) ? null : ref.get();
1307
1308 if (br == null) {
1309 br = new BufferRecycler();
1310 _recyclerRef.set(new SoftReference<BufferRecycler>(br));
1311 }
1312 return br;
1313 }
1314
1315 /**
1316 * Helper methods used for constructing an optimal stream for
1317 * parsers to use, when input is to be read from an URL.
1318 * This helps when reading file content via URL.
1319 */
1320 protected InputStream _optimizedStreamFromURL(URL url)
1321 throws IOException
1322 {
1323 if ("file".equals(url.getProtocol())) {
1324 /* Can not do this if the path refers
1325 * to a network drive on windows. This fixes the problem;
1326 * might not be needed on all platforms (NFS?), but should not
1327 * matter a lot: performance penalty of extra wrapping is more
1328 * relevant when accessing local file system.
1329 */
1330 String host = url.getHost();
1331 if (host == null || host.length() == 0) {
1332 return new FileInputStream(url.getPath());
1333 }
1334 }
1335 return url.openStream();
1336 }
1337}