1 /* Jackson JSON-processor. 2 * 3 * Copyright (c) 2007- Tatu Saloranta, tatu.saloranta@iki.fi 4 */ 5 package com.fasterxml.jackson.core; 6 7 import java.io.*; 8 import java.math.BigDecimal; 9 import java.math.BigInteger; 10 import java.util.concurrent.atomic.AtomicBoolean; 11 import java.util.concurrent.atomic.AtomicInteger; 12 import java.util.concurrent.atomic.AtomicLong; 13 14 import com.fasterxml.jackson.core.JsonParser.NumberType; 15 import com.fasterxml.jackson.core.io.CharacterEscapes; 16 import com.fasterxml.jackson.core.type.WritableTypeId; 17 import com.fasterxml.jackson.core.type.WritableTypeId.Inclusion; 18 import com.fasterxml.jackson.core.util.JacksonFeatureSet; 19 import com.fasterxml.jackson.core.util.VersionUtil; 20 21 import static com.fasterxml.jackson.core.JsonTokenId.*; 22 23 /** 24 * Base class that defines public API for writing JSON content. 25 * Instances are created using factory methods of 26 * a {@link JsonFactory} instance. 27 * 28 * @author Tatu Saloranta 29 */ 30 public abstract class JsonGenerator 31 implements Closeable, Flushable, Versioned 32 { 33 /** 34 * Default set of {@link StreamReadCapability}ies that may be used as 35 * basis for format-specific readers (or as bogus instance if non-null 36 * set needs to be passed). 37 * 38 * @since 2.12 39 */ 40 protected final static JacksonFeatureSet<StreamWriteCapability> DEFAULT_WRITE_CAPABILITIES 41 = JacksonFeatureSet.fromDefaults(StreamWriteCapability.values()); 42 43 /** 44 * Default set of {@link StreamReadCapability}ies for typical textual formats, 45 * to use either as-is, or as a base with possible differences. 46 * 47 * @since 2.12 48 */ 49 protected final static JacksonFeatureSet<StreamWriteCapability> DEFAULT_TEXTUAL_WRITE_CAPABILITIES 50 = DEFAULT_WRITE_CAPABILITIES.with(StreamWriteCapability.CAN_WRITE_FORMATTED_NUMBERS); 51 52 /** 53 * Default set of {@link StreamReadCapability}ies for typical binary formats, 54 * to use either as-is, or as a base with possible differences. 55 * 56 * @since 2.12 57 */ 58 protected final static JacksonFeatureSet<StreamWriteCapability> DEFAULT_BINARY_WRITE_CAPABILITIES 59 = DEFAULT_WRITE_CAPABILITIES.with(StreamWriteCapability.CAN_WRITE_BINARY_NATIVELY); 60 61 /** 62 * Enumeration that defines all togglable features for generators. 63 */ 64 public enum Feature { 65 // // Low-level I/O / content features 66 67 /** 68 * Feature that determines whether generator will automatically 69 * close underlying output target that is NOT owned by the 70 * generator. 71 * If disabled, calling application has to separately 72 * close the underlying {@link OutputStream} and {@link Writer} 73 * instances used to create the generator. If enabled, generator 74 * will handle closing, as long as generator itself gets closed: 75 * this happens when end-of-input is encountered, or generator 76 * is closed by a call to {@link JsonGenerator#close}. 77 *<p> 78 * Feature is enabled by default. 79 */ 80 AUTO_CLOSE_TARGET(true), 81 82 /** 83 * Feature that determines what happens when the generator is 84 * closed while there are still unmatched 85 * {@link JsonToken#START_ARRAY} or {@link JsonToken#START_OBJECT} 86 * entries in output content. If enabled, such Array(s) and/or 87 * Object(s) are automatically closed; if disabled, nothing 88 * specific is done. 89 *<p> 90 * Feature is enabled by default. 91 */ 92 AUTO_CLOSE_JSON_CONTENT(true), 93 94 /** 95 * Feature that specifies that calls to {@link #flush} will cause 96 * matching <code>flush()</code> to underlying {@link OutputStream} 97 * or {@link Writer}; if disabled this will not be done. 98 * Main reason to disable this feature is to prevent flushing at 99 * generator level, if it is not possible to prevent method being 100 * called by other code (like <code>ObjectMapper</code> or third 101 * party libraries). 102 *<p> 103 * Feature is enabled by default. 104 */ 105 FLUSH_PASSED_TO_STREAM(true), 106 107 // // Quoting-related features 108 109 /** 110 * Feature that determines whether JSON Object field names are 111 * quoted using double-quotes, as specified by JSON specification 112 * or not. Ability to disable quoting was added to support use 113 * cases where they are not usually expected, which most commonly 114 * occurs when used straight from Javascript. 115 *<p> 116 * Feature is enabled by default (since it is required by JSON specification). 117 * 118 * @deprecated Since 2.10 use {@link com.fasterxml.jackson.core.json.JsonWriteFeature#QUOTE_FIELD_NAMES} instead 119 */ 120 @Deprecated 121 QUOTE_FIELD_NAMES(true), 122 123 /** 124 * Feature that determines whether "exceptional" (not real number) 125 * float/double values are output as quoted strings. 126 * The values checked are Double.Nan, 127 * Double.POSITIVE_INFINITY and Double.NEGATIVE_INIFINTY (and 128 * associated Float values). 129 * If feature is disabled, these numbers are still output using 130 * associated literal values, resulting in non-conformant 131 * output. 132 *<p> 133 * Feature is enabled by default. 134 * 135 * @deprecated Since 2.10 use {@link com.fasterxml.jackson.core.json.JsonWriteFeature#WRITE_NAN_AS_STRINGS} instead 136 */ 137 @Deprecated 138 QUOTE_NON_NUMERIC_NUMBERS(true), 139 140 // // Character escaping features 141 142 /** 143 * Feature that specifies that all characters beyond 7-bit ASCII 144 * range (i.e. code points of 128 and above) need to be output 145 * using format-specific escapes (for JSON, backslash escapes), 146 * if format uses escaping mechanisms (which is generally true 147 * for textual formats but not for binary formats). 148 *<p> 149 * Note that this setting may not necessarily make sense for all 150 * data formats (for example, binary formats typically do not use 151 * any escaping mechanisms; and some textual formats do not have 152 * general-purpose escaping); if so, settings is simply ignored. 153 * Put another way, effects of this feature are data-format specific. 154 *<p> 155 * Feature is disabled by default. 156 * 157 * @deprecated Since 2.10 use {@link com.fasterxml.jackson.core.json.JsonWriteFeature#ESCAPE_NON_ASCII} instead 158 */ 159 @Deprecated 160 ESCAPE_NON_ASCII(false), 161 162 // // Datatype coercion features 163 164 /** 165 * Feature that forces all Java numbers to be written as Strings, 166 * even if the underlying data format has non-textual representation 167 * (which is the case for JSON as well as all binary formats). 168 * Default state is 'false', meaning that Java numbers are to 169 * be serialized using basic numeric serialization (as JSON 170 * numbers, integral or floating point, for example). 171 * If enabled, all such numeric values are instead written out as 172 * textual values (which for JSON means quoted in double-quotes). 173 *<p> 174 * One use case is to avoid problems with Javascript limitations: 175 * since Javascript standard specifies that all number handling 176 * should be done using 64-bit IEEE 754 floating point values, 177 * result being that some 64-bit integer values can not be 178 * accurately represent (as mantissa is only 51 bit wide). 179 *<p> 180 * Feature is disabled by default. 181 * 182 * @deprecated Since 2.10 use {@link com.fasterxml.jackson.core.json.JsonWriteFeature#WRITE_NUMBERS_AS_STRINGS} instead 183 */ 184 @Deprecated 185 WRITE_NUMBERS_AS_STRINGS(false), 186 187 /** 188 * Feature that determines whether {@link java.math.BigDecimal} entries are 189 * serialized using {@link java.math.BigDecimal#toPlainString()} to prevent 190 * values to be written using scientific notation. 191 *<p> 192 * NOTE: only affects generators that serialize {@link java.math.BigDecimal}s 193 * using textual representation (textual formats but potentially some binary 194 * formats). 195 *<p> 196 * Feature is disabled by default, so default output mode is used; this generally 197 * depends on how {@link BigDecimal} has been created. 198 * 199 * @since 2.3 200 */ 201 WRITE_BIGDECIMAL_AS_PLAIN(false), 202 203 // // Schema/Validity support features 204 205 /** 206 * Feature that determines whether {@link JsonGenerator} will explicitly 207 * check that no duplicate JSON Object field names are written. 208 * If enabled, generator will check all names within context and report 209 * duplicates by throwing a {@link JsonGenerationException}; if disabled, 210 * no such checking will be done. Assumption in latter case is 211 * that caller takes care of not trying to write duplicate names. 212 *<p> 213 * Note that enabling this feature will incur performance overhead 214 * due to having to store and check additional information. 215 *<p> 216 * Feature is disabled by default. 217 * 218 * @since 2.3 219 */ 220 STRICT_DUPLICATE_DETECTION(false), 221 222 /** 223 * Feature that determines what to do if the underlying data format requires knowledge 224 * of all properties to output, and if no definition is found for a property that 225 * caller tries to write. If enabled, such properties will be quietly ignored; 226 * if disabled, a {@link JsonProcessingException} will be thrown to indicate the 227 * problem. 228 * Typically most textual data formats do NOT require schema information (although 229 * some do, such as CSV), whereas many binary data formats do require definitions 230 * (such as Avro, protobuf), although not all (Smile, CBOR, BSON and MessagePack do not). 231 *<p> 232 * Note that support for this feature is implemented by individual data format 233 * module, if (and only if) it makes sense for the format in question. For JSON, 234 * for example, this feature has no effect as properties need not be pre-defined. 235 *<p> 236 * Feature is disabled by default, meaning that if the underlying data format 237 * requires knowledge of all properties to output, attempts to write an unknown 238 * property will result in a {@link JsonProcessingException} 239 * 240 * @since 2.5 241 */ 242 IGNORE_UNKNOWN(false), 243 ; 244 245 private final boolean _defaultState; 246 private final int _mask; 247 248 /** 249 * Method that calculates bit set (flags) of all features that 250 * are enabled by default. 251 */ collectDefaults()252 public static int collectDefaults() 253 { 254 int flags = 0; 255 for (Feature f : values()) { 256 if (f.enabledByDefault()) { 257 flags |= f.getMask(); 258 } 259 } 260 return flags; 261 } 262 Feature(boolean defaultState)263 private Feature(boolean defaultState) { 264 _defaultState = defaultState; 265 _mask = (1 << ordinal()); 266 } 267 enabledByDefault()268 public boolean enabledByDefault() { return _defaultState; } 269 270 /** 271 * @since 2.3 272 */ enabledIn(int flags)273 public boolean enabledIn(int flags) { return (flags & _mask) != 0; } 274 getMask()275 public int getMask() { return _mask; } 276 } 277 278 /* 279 /********************************************************** 280 /* Configuration 281 /********************************************************** 282 */ 283 284 /** 285 * Object that handles pretty-printing (usually additional 286 * white space to make results more human-readable) during 287 * output. If null, no pretty-printing is done. 288 */ 289 protected PrettyPrinter _cfgPrettyPrinter; 290 291 /* 292 /********************************************************** 293 /* Construction, initialization 294 /********************************************************** 295 */ 296 JsonGenerator()297 protected JsonGenerator() { } 298 299 /** 300 * Method that can be called to set or reset the object to 301 * use for writing Java objects as JsonContent 302 * (using method {@link #writeObject}). 303 * 304 * @return Generator itself (this), to allow chaining 305 */ setCodec(ObjectCodec oc)306 public abstract JsonGenerator setCodec(ObjectCodec oc); 307 308 /** 309 * Method for accessing the object used for writing Java 310 * object as JSON content 311 * (using method {@link #writeObject}). 312 */ getCodec()313 public abstract ObjectCodec getCodec(); 314 315 /** 316 * Accessor for finding out version of the bundle that provided this generator instance. 317 */ 318 @Override version()319 public abstract Version version(); 320 321 /* 322 /********************************************************** 323 /* Public API, Feature configuration 324 /********************************************************** 325 */ 326 327 /** 328 * Method for enabling specified parser features: 329 * check {@link Feature} for list of available features. 330 * 331 * @return Generator itself (this), to allow chaining 332 */ enable(Feature f)333 public abstract JsonGenerator enable(Feature f); 334 335 /** 336 * Method for disabling specified features 337 * (check {@link Feature} for list of features) 338 * 339 * @return Generator itself (this), to allow chaining 340 */ disable(Feature f)341 public abstract JsonGenerator disable(Feature f); 342 343 /** 344 * Method for enabling or disabling specified feature: 345 * check {@link Feature} for list of available features. 346 * 347 * @return Generator itself (this), to allow chaining 348 */ configure(Feature f, boolean state)349 public final JsonGenerator configure(Feature f, boolean state) { 350 if (state) enable(f); else disable(f); 351 return this; 352 } 353 354 /** 355 * Method for checking whether given feature is enabled. 356 * Check {@link Feature} for list of available features. 357 */ isEnabled(Feature f)358 public abstract boolean isEnabled(Feature f); 359 360 /** 361 * @since 2.10 362 */ isEnabled(StreamWriteFeature f)363 public boolean isEnabled(StreamWriteFeature f) { 364 return isEnabled(f.mappedFeature()); 365 } 366 367 /** 368 * Bulk access method for getting state of all standard (non-dataformat-specific) 369 * {@link JsonGenerator.Feature}s. 370 * 371 * @return Bit mask that defines current states of all standard {@link JsonGenerator.Feature}s. 372 * 373 * @since 2.3 374 */ getFeatureMask()375 public abstract int getFeatureMask(); 376 377 /** 378 * Bulk set method for (re)setting states of all standard {@link Feature}s 379 * 380 * @since 2.3 381 * 382 * @param values Bitmask that defines which {@link Feature}s are enabled 383 * and which disabled 384 * 385 * @return This parser object, to allow chaining of calls 386 * 387 * @deprecated Since 2.7, use {@link #overrideStdFeatures(int, int)} instead -- remove from 2.9 388 */ 389 @Deprecated setFeatureMask(int values)390 public abstract JsonGenerator setFeatureMask(int values); 391 392 /** 393 * Bulk set method for (re)setting states of features specified by <code>mask</code>. 394 * Functionally equivalent to 395 *<code> 396 * int oldState = getFeatureMask(); 397 * int newState = (oldState & ~mask) | (values & mask); 398 * setFeatureMask(newState); 399 *</code> 400 * but preferred as this lets caller more efficiently specify actual changes made. 401 * 402 * @param values Bit mask of set/clear state for features to change 403 * @param mask Bit mask of features to change 404 * 405 * @since 2.6 406 */ overrideStdFeatures(int values, int mask)407 public JsonGenerator overrideStdFeatures(int values, int mask) { 408 int oldState = getFeatureMask(); 409 int newState = (oldState & ~mask) | (values & mask); 410 return setFeatureMask(newState); 411 } 412 413 /** 414 * Bulk access method for getting state of all {@link FormatFeature}s, format-specific 415 * on/off configuration settings. 416 * 417 * @return Bit mask that defines current states of all standard {@link FormatFeature}s. 418 * 419 * @since 2.6 420 */ getFormatFeatures()421 public int getFormatFeatures() { 422 return 0; 423 } 424 425 /** 426 * Bulk set method for (re)setting states of {@link FormatFeature}s, 427 * by specifying values (set / clear) along with a mask, to determine 428 * which features to change, if any. 429 *<p> 430 * Default implementation will simply throw an exception to indicate that 431 * the generator implementation does not support any {@link FormatFeature}s. 432 * 433 * @param values Bit mask of set/clear state for features to change 434 * @param mask Bit mask of features to change 435 * 436 * @since 2.6 437 */ overrideFormatFeatures(int values, int mask)438 public JsonGenerator overrideFormatFeatures(int values, int mask) { 439 // 08-Oct-2018, tatu: For 2.10 we actually do get `JsonWriteFeature`s, although they 440 // are (for 2.x only, not for 3.x) mapper to legacy settings. So do not freak out: 441 // throw new IllegalArgumentException("No FormatFeatures defined for generator of type "+getClass().getName()); 442 return this; 443 } 444 445 /* 446 /********************************************************** 447 /* Public API, Schema configuration 448 /********************************************************** 449 */ 450 451 /** 452 * Method to call to make this generator use specified schema. 453 * Method must be called before generating any content, right after instance 454 * has been created. 455 * Note that not all generators support schemas; and those that do usually only 456 * accept specific types of schemas: ones defined for data format this generator 457 * produces. 458 *<p> 459 * If generator does not support specified schema, {@link UnsupportedOperationException} 460 * is thrown. 461 * 462 * @param schema Schema to use 463 * 464 * @throws UnsupportedOperationException if generator does not support schema 465 */ setSchema(FormatSchema schema)466 public void setSchema(FormatSchema schema) { 467 throw new UnsupportedOperationException(String.format( 468 "Generator of type %s does not support schema of type '%s'", 469 getClass().getName(), schema.getSchemaType())); 470 } 471 472 /** 473 * Method for accessing Schema that this parser uses, if any. 474 * Default implementation returns null. 475 * 476 * @since 2.1 477 */ getSchema()478 public FormatSchema getSchema() { return null; } 479 480 /* 481 /********************************************************** 482 /* Public API, other configuration 483 /********************************************************** 484 */ 485 486 /** 487 * Method for setting a custom pretty printer, which is usually 488 * used to add indentation for improved human readability. 489 * By default, generator does not do pretty printing. 490 *<p> 491 * To use the default pretty printer that comes with core 492 * Jackson distribution, call {@link #useDefaultPrettyPrinter} 493 * instead. 494 * 495 * @return Generator itself (this), to allow chaining 496 */ setPrettyPrinter(PrettyPrinter pp)497 public JsonGenerator setPrettyPrinter(PrettyPrinter pp) { 498 _cfgPrettyPrinter = pp; 499 return this; 500 } 501 502 /** 503 * Accessor for checking whether this generator has a configured 504 * {@link PrettyPrinter}; returns it if so, null if none configured. 505 * 506 * @since 2.1 507 */ getPrettyPrinter()508 public PrettyPrinter getPrettyPrinter() { 509 return _cfgPrettyPrinter; 510 } 511 512 /** 513 * Convenience method for enabling pretty-printing using 514 * the default pretty printer 515 * ({@link com.fasterxml.jackson.core.util.DefaultPrettyPrinter}). 516 * 517 * @return Generator itself (this), to allow chaining 518 */ useDefaultPrettyPrinter()519 public abstract JsonGenerator useDefaultPrettyPrinter(); 520 521 /** 522 * Method that can be called to request that generator escapes 523 * all character codes above specified code point (if positive value); 524 * or, to not escape any characters except for ones that must be 525 * escaped for the data format (if -1). 526 * To force escaping of all non-ASCII characters, for example, 527 * this method would be called with value of 127. 528 *<p> 529 * Note that generators are NOT required to support setting of value 530 * higher than 127, because there are other ways to affect quoting 531 * (or lack thereof) of character codes between 0 and 127. 532 * Not all generators support concept of escaping, either; if so, 533 * calling this method will have no effect. 534 *<p> 535 * Default implementation does nothing; sub-classes need to redefine 536 * it according to rules of supported data format. 537 * 538 * @param charCode Either -1 to indicate that no additional escaping 539 * is to be done; or highest code point not to escape (meaning higher 540 * ones will be), if positive value. 541 */ setHighestNonEscapedChar(int charCode)542 public JsonGenerator setHighestNonEscapedChar(int charCode) { return this; } 543 544 /** 545 * Accessor method for testing what is the highest unescaped character 546 * configured for this generator. This may be either positive value 547 * (when escaping configuration has been set and is in effect), or 548 * 0 to indicate that no additional escaping is in effect. 549 * Some generators may not support additional escaping: for example, 550 * generators for binary formats that do not use escaping should 551 * simply return 0. 552 * 553 * @return Currently active limitation for highest non-escaped character, 554 * if defined; or 0 to indicate no additional escaping is performed. 555 */ getHighestEscapedChar()556 public int getHighestEscapedChar() { return 0; } 557 558 /** 559 * Method for accessing custom escapes factory uses for {@link JsonGenerator}s 560 * it creates. 561 */ getCharacterEscapes()562 public CharacterEscapes getCharacterEscapes() { return null; } 563 564 /** 565 * Method for defining custom escapes factory uses for {@link JsonGenerator}s 566 * it creates. 567 *<p> 568 * Default implementation does nothing and simply returns this instance. 569 */ setCharacterEscapes(CharacterEscapes esc)570 public JsonGenerator setCharacterEscapes(CharacterEscapes esc) { return this; } 571 572 /** 573 * Method that allows overriding String used for separating root-level 574 * JSON values (default is single space character) 575 *<p> 576 * Default implementation throws {@link UnsupportedOperationException}. 577 * 578 * @param sep Separator to use, if any; null means that no separator is 579 * automatically added 580 * 581 * @since 2.1 582 */ setRootValueSeparator(SerializableString sep)583 public JsonGenerator setRootValueSeparator(SerializableString sep) { 584 throw new UnsupportedOperationException(); 585 } 586 587 /* 588 /********************************************************** 589 /* Public API, output state access 590 /********************************************************** 591 */ 592 593 /** 594 * Method that can be used to get access to object that is used 595 * as target for generated output; this is usually either 596 * {@link OutputStream} or {@link Writer}, depending on what 597 * generator was constructed with. 598 * Note that returned value may be null in some cases; including 599 * case where implementation does not want to exposed raw 600 * source to caller. 601 * In cases where output has been decorated, object returned here 602 * is the decorated version; this allows some level of interaction 603 * between users of generator and decorator object. 604 *<p> 605 * In general use of this accessor should be considered as 606 * "last effort", i.e. only used if no other mechanism is applicable. 607 */ getOutputTarget()608 public Object getOutputTarget() { 609 return null; 610 } 611 612 /** 613 * Method for verifying amount of content that is buffered by generator 614 * but not yet flushed to the underlying target (stream, writer), 615 * in units (byte, char) that the generator implementation uses for buffering; 616 * or -1 if this information is not available. 617 * Unit used is often the same as the unit of underlying target (that is, 618 * `byte` for {@link java.io.OutputStream}, `char` for {@link java.io.Writer}), 619 * but may differ if buffering is done before encoding. 620 * Default JSON-backed implementations do use matching units. 621 *<p> 622 * Note: non-JSON implementations will be retrofitted for 2.6 and beyond; 623 * please report if you see -1 (missing override) 624 * 625 * @return Amount of content buffered in internal units, if amount known and 626 * accessible; -1 if not accessible. 627 * 628 * @since 2.6 629 */ getOutputBuffered()630 public int getOutputBuffered() { 631 return -1; 632 } 633 634 /** 635 * Helper method, usually equivalent to: 636 *<code> 637 * getOutputContext().getCurrentValue(); 638 *</code> 639 *<p> 640 * Note that "current value" is NOT populated (or used) by Streaming parser; 641 * it is only used by higher-level data-binding functionality. 642 * The reason it is included here is that it can be stored and accessed hierarchically, 643 * and gets passed through data-binding. 644 * 645 * @since 2.5 646 */ getCurrentValue()647 public Object getCurrentValue() { 648 JsonStreamContext ctxt = getOutputContext(); 649 return (ctxt == null) ? null : ctxt.getCurrentValue(); 650 } 651 652 /** 653 * Helper method, usually equivalent to: 654 *<code> 655 * getOutputContext().setCurrentValue(v); 656 *</code> 657 * 658 * @since 2.5 659 */ setCurrentValue(Object v)660 public void setCurrentValue(Object v) { 661 JsonStreamContext ctxt = getOutputContext(); 662 if (ctxt != null) { 663 ctxt.setCurrentValue(v); 664 } 665 } 666 667 /* 668 /********************************************************** 669 /* Public API, capability introspection methods 670 /********************************************************** 671 */ 672 673 /** 674 * Method that can be used to verify that given schema can be used with 675 * this generator (using {@link #setSchema}). 676 * 677 * @param schema Schema to check 678 * 679 * @return True if this generator can use given schema; false if not 680 */ canUseSchema(FormatSchema schema)681 public boolean canUseSchema(FormatSchema schema) { return false; } 682 683 /** 684 * Introspection method that may be called to see if the underlying 685 * data format supports some kind of Object Ids natively (many do not; 686 * for example, JSON doesn't). 687 * This method <b>must</b> be called prior to calling 688 * {@link #writeObjectId} or {@link #writeObjectRef}. 689 *<p> 690 * Default implementation returns false; overridden by data formats 691 * that do support native Object Ids. Caller is expected to either 692 * use a non-native notation (explicit property or such), or fail, 693 * in case it can not use native object ids. 694 * 695 * @since 2.3 696 */ canWriteObjectId()697 public boolean canWriteObjectId() { return false; } 698 699 /** 700 * Introspection method that may be called to see if the underlying 701 * data format supports some kind of Type Ids natively (many do not; 702 * for example, JSON doesn't). 703 * This method <b>must</b> be called prior to calling 704 * {@link #writeTypeId}. 705 *<p> 706 * Default implementation returns false; overridden by data formats 707 * that do support native Type Ids. Caller is expected to either 708 * use a non-native notation (explicit property or such), or fail, 709 * in case it can not use native type ids. 710 * 711 * @since 2.3 712 */ canWriteTypeId()713 public boolean canWriteTypeId() { return false; } 714 715 /** 716 * Introspection method that may be called to see if the underlying 717 * data format supports "native" binary data; that is, an efficient 718 * output of binary content without encoding. 719 *<p> 720 * Default implementation returns false; overridden by data formats 721 * that do support native binary content. 722 * 723 * @since 2.3 724 */ canWriteBinaryNatively()725 public boolean canWriteBinaryNatively() { return false; } 726 727 /** 728 * Introspection method to call to check whether it is ok to omit 729 * writing of Object fields or not. Most formats do allow omission, 730 * but certain positional formats (such as CSV) require output of 731 * placeholders, even if no real values are to be emitted. 732 * 733 * @since 2.3 734 */ canOmitFields()735 public boolean canOmitFields() { return true; } 736 737 /** 738 * Introspection method to call to check whether it is possible 739 * to write numbers using {@link #writeNumber(java.lang.String)} 740 * using possible custom format, or not. Typically textual formats 741 * allow this (and JSON specifically does), whereas binary formats 742 * do not allow this (except by writing them as Strings). 743 * Usual reason for calling this method is to check whether custom 744 * formatting of numbers may be applied by higher-level code (databinding) 745 * or not. 746 * 747 * @since 2.8 748 */ canWriteFormattedNumbers()749 public boolean canWriteFormattedNumbers() { return false; } 750 751 /** 752 * Accessor for getting metadata on capabilities of this parser, based on 753 * underlying data format being read (directly or indirectly). 754 * 755 * @return Set of read capabilities for content to read via this parser 756 * 757 * @since 2.12 758 */ getWriteCapabilities()759 public JacksonFeatureSet<StreamWriteCapability> getWriteCapabilities() { 760 return DEFAULT_WRITE_CAPABILITIES; 761 } 762 763 /* 764 /********************************************************** 765 /* Public API, write methods, structural 766 /********************************************************** 767 */ 768 769 /** 770 * Method for writing starting marker of a Array value 771 * (for JSON this is character '['; plus possible white space decoration 772 * if pretty-printing is enabled). 773 *<p> 774 * Array values can be written in any context where values 775 * are allowed: meaning everywhere except for when 776 * a field name is expected. 777 */ writeStartArray()778 public abstract void writeStartArray() throws IOException; 779 780 /** 781 * Method for writing start marker of an Array value, similar 782 * to {@link #writeStartArray()}, but also specifying how many 783 * elements will be written for the array before calling 784 * {@link #writeEndArray()}. 785 *<p> 786 * Default implementation simply calls {@link #writeStartArray()}. 787 * 788 * @param size Number of elements this array will have: actual 789 * number of values written (before matching call to 790 * {@link #writeEndArray()} MUST match; generator MAY verify 791 * this is the case. 792 * 793 * @since 2.4 794 * 795 * @deprecated Since 2.12 Use {@link #writeStartArray(Object, int)} instead 796 */ 797 @Deprecated writeStartArray(int size)798 public void writeStartArray(int size) throws IOException { 799 writeStartArray(); 800 } 801 802 /** 803 * @since 2.10 804 */ writeStartArray(Object forValue)805 public void writeStartArray(Object forValue) throws IOException { 806 writeStartArray(); 807 setCurrentValue(forValue); 808 } 809 810 /** 811 * @since 2.10 812 */ writeStartArray(Object forValue, int size)813 public void writeStartArray(Object forValue, int size) throws IOException { 814 writeStartArray(size); 815 setCurrentValue(forValue); 816 } 817 818 /** 819 * Method for writing closing marker of a JSON Array value 820 * (character ']'; plus possible white space decoration 821 * if pretty-printing is enabled). 822 *<p> 823 * Marker can be written if the innermost structured type 824 * is Array. 825 */ writeEndArray()826 public abstract void writeEndArray() throws IOException; 827 828 /** 829 * Method for writing starting marker of an Object value 830 * (character '{'; plus possible white space decoration 831 * if pretty-printing is enabled). 832 *<p> 833 * Object values can be written in any context where values 834 * are allowed: meaning everywhere except for when 835 * a field name is expected. 836 */ writeStartObject()837 public abstract void writeStartObject() throws IOException; 838 839 /** 840 * Method for writing starting marker of an Object value 841 * to represent the given Java Object value. 842 * Argument is offered as metadata, but more 843 * importantly it should be assigned as the "current value" 844 * for the Object content that gets constructed and initialized. 845 *<p> 846 * Object values can be written in any context where values 847 * are allowed: meaning everywhere except for when 848 * a field name is expected. 849 * 850 * @since 2.8 851 */ writeStartObject(Object forValue)852 public void writeStartObject(Object forValue) throws IOException 853 { 854 writeStartObject(); 855 setCurrentValue(forValue); 856 } 857 858 /** 859 * Method for writing starting marker of an Object value 860 * to represent the given Java Object value. 861 * Argument is offered as metadata, but more 862 * importantly it should be assigned as the "current value" 863 * for the Object content that gets constructed and initialized. 864 * In addition, caller knows number of key/value pairs ("properties") 865 * that will get written for the Object value: this is relevant for 866 * some format backends (but not, as an example, for JSON). 867 *<p> 868 * Object values can be written in any context where values 869 * are allowed: meaning everywhere except for when 870 * a field name is expected. 871 * 872 * @since 2.10 873 */ writeStartObject(Object forValue, int size)874 public void writeStartObject(Object forValue, int size) throws IOException 875 { 876 writeStartObject(); 877 setCurrentValue(forValue); 878 } 879 880 /** 881 * Method for writing closing marker of an Object value 882 * (character '}'; plus possible white space decoration 883 * if pretty-printing is enabled). 884 *<p> 885 * Marker can be written if the innermost structured type 886 * is Object, and the last written event was either a 887 * complete value, or START-OBJECT marker (see JSON specification 888 * for more details). 889 */ writeEndObject()890 public abstract void writeEndObject() throws IOException; 891 892 /** 893 * Method for writing a field name (JSON String surrounded by 894 * double quotes: syntactically identical to a JSON String value), 895 * possibly decorated by white space if pretty-printing is enabled. 896 *<p> 897 * Field names can only be written in Object context (check out 898 * JSON specification for details), when field name is expected 899 * (field names alternate with values). 900 */ writeFieldName(String name)901 public abstract void writeFieldName(String name) throws IOException; 902 903 /** 904 * Method similar to {@link #writeFieldName(String)}, main difference 905 * being that it may perform better as some of processing (such as 906 * quoting of certain characters, or encoding into external encoding 907 * if supported by generator) can be done just once and reused for 908 * later calls. 909 *<p> 910 * Default implementation simple uses unprocessed name container in 911 * serialized String; implementations are strongly encouraged to make 912 * use of more efficient methods argument object has. 913 */ writeFieldName(SerializableString name)914 public abstract void writeFieldName(SerializableString name) throws IOException; 915 916 /** 917 * Alternative to {@link #writeFieldName(String)} that may be used 918 * in cases where property key is of numeric type; either where 919 * underlying format supports such notion (some binary formats do, 920 * unlike JSON), or for convenient conversion into String presentation. 921 * Default implementation will simply convert id into <code>String</code> 922 * and call {@link #writeFieldName(String)}. 923 * 924 * @since 2.8 925 */ writeFieldId(long id)926 public void writeFieldId(long id) throws IOException { 927 writeFieldName(Long.toString(id)); 928 } 929 930 /* 931 /********************************************************** 932 /* Public API, write methods, scalar arrays (2.8) 933 /********************************************************** 934 */ 935 936 /** 937 * Value write method that can be called to write a single 938 * array (sequence of {@link JsonToken#START_ARRAY}, zero or 939 * more {@link JsonToken#VALUE_NUMBER_INT}, {@link JsonToken#END_ARRAY}) 940 * 941 * @since 2.8 942 * 943 * @param array Array that contains values to write 944 * @param offset Offset of the first element to write, within array 945 * @param length Number of elements in array to write, from `offset` to `offset + len - 1` 946 */ writeArray(int[] array, int offset, int length)947 public void writeArray(int[] array, int offset, int length) throws IOException 948 { 949 if (array == null) { 950 throw new IllegalArgumentException("null array"); 951 } 952 _verifyOffsets(array.length, offset, length); 953 writeStartArray(array, length); 954 for (int i = offset, end = offset+length; i < end; ++i) { 955 writeNumber(array[i]); 956 } 957 writeEndArray(); 958 } 959 960 /** 961 * Value write method that can be called to write a single 962 * array (sequence of {@link JsonToken#START_ARRAY}, zero or 963 * more {@link JsonToken#VALUE_NUMBER_INT}, {@link JsonToken#END_ARRAY}) 964 * 965 * @since 2.8 966 * 967 * @param array Array that contains values to write 968 * @param offset Offset of the first element to write, within array 969 * @param length Number of elements in array to write, from `offset` to `offset + len - 1` 970 */ writeArray(long[] array, int offset, int length)971 public void writeArray(long[] array, int offset, int length) throws IOException 972 { 973 if (array == null) { 974 throw new IllegalArgumentException("null array"); 975 } 976 _verifyOffsets(array.length, offset, length); 977 writeStartArray(array, length); 978 for (int i = offset, end = offset+length; i < end; ++i) { 979 writeNumber(array[i]); 980 } 981 writeEndArray(); 982 } 983 984 /** 985 * Value write method that can be called to write a single 986 * array (sequence of {@link JsonToken#START_ARRAY}, zero or 987 * more {@link JsonToken#VALUE_NUMBER_FLOAT}, {@link JsonToken#END_ARRAY}) 988 * 989 * @since 2.8 990 * 991 * @param array Array that contains values to write 992 * @param offset Offset of the first element to write, within array 993 * @param length Number of elements in array to write, from `offset` to `offset + len - 1` 994 */ writeArray(double[] array, int offset, int length)995 public void writeArray(double[] array, int offset, int length) throws IOException 996 { 997 if (array == null) { 998 throw new IllegalArgumentException("null array"); 999 } 1000 _verifyOffsets(array.length, offset, length); 1001 writeStartArray(array, length); 1002 for (int i = offset, end = offset+length; i < end; ++i) { 1003 writeNumber(array[i]); 1004 } 1005 writeEndArray(); 1006 } 1007 1008 /** 1009 * Value write method that can be called to write a single 1010 * array (sequence of {@link JsonToken#START_ARRAY}, zero or 1011 * more {@link JsonToken#VALUE_STRING}, {@link JsonToken#END_ARRAY}) 1012 * 1013 * @since 2.11 1014 * 1015 * @param array Array that contains values to write 1016 * @param offset Offset of the first element to write, within array 1017 * @param length Number of elements in array to write, from `offset` to `offset + len - 1` 1018 */ writeArray(String[] array, int offset, int length)1019 public void writeArray(String[] array, int offset, int length) throws IOException 1020 { 1021 if (array == null) { 1022 throw new IllegalArgumentException("null array"); 1023 } 1024 _verifyOffsets(array.length, offset, length); 1025 writeStartArray(array, length); 1026 for (int i = offset, end = offset+length; i < end; ++i) { 1027 writeString(array[i]); 1028 } 1029 writeEndArray(); 1030 } 1031 1032 /* 1033 /********************************************************** 1034 /* Public API, write methods, text/String values 1035 /********************************************************** 1036 */ 1037 1038 /** 1039 * Method for outputting a String value. Depending on context 1040 * this means either array element, (object) field value or 1041 * a stand alone String; but in all cases, String will be 1042 * surrounded in double quotes, and contents will be properly 1043 * escaped as required by JSON specification. 1044 */ writeString(String text)1045 public abstract void writeString(String text) throws IOException; 1046 1047 /** 1048 * Method for outputting a String value. Depending on context 1049 * this means either array element, (object) field value or 1050 * a stand alone String; but in all cases, String will be 1051 * surrounded in double quotes, and contents will be properly 1052 * escaped as required by JSON specification. 1053 * If the reader is null, then write a null. 1054 * If len is < 0, then write all contents of the reader. 1055 * Otherwise, write only len characters. 1056 * 1057 * @since 2.9 1058 */ writeString(Reader reader, int len)1059 public void writeString(Reader reader, int len) throws IOException { 1060 // Let's implement this as "unsupported" to make it easier to add new parser impls 1061 _reportUnsupportedOperation(); 1062 } 1063 1064 /** 1065 * Method for outputting a String value. Depending on context 1066 * this means either array element, (object) field value or 1067 * a stand alone String; but in all cases, String will be 1068 * surrounded in double quotes, and contents will be properly 1069 * escaped as required by JSON specification. 1070 */ writeString(char[] text, int offset, int len)1071 public abstract void writeString(char[] text, int offset, int len) throws IOException; 1072 1073 /** 1074 * Method similar to {@link #writeString(String)}, but that takes 1075 * {@link SerializableString} which can make this potentially 1076 * more efficient to call as generator may be able to reuse 1077 * quoted and/or encoded representation. 1078 *<p> 1079 * Default implementation just calls {@link #writeString(String)}; 1080 * sub-classes should override it with more efficient implementation 1081 * if possible. 1082 */ writeString(SerializableString text)1083 public abstract void writeString(SerializableString text) throws IOException; 1084 1085 /** 1086 * Method similar to {@link #writeString(String)} but that takes as 1087 * its input a UTF-8 encoded String that is to be output as-is, without additional 1088 * escaping (type of which depends on data format; backslashes for JSON). 1089 * However, quoting that data format requires (like double-quotes for JSON) will be added 1090 * around the value if and as necessary. 1091 *<p> 1092 * Note that some backends may choose not to support this method: for 1093 * example, if underlying destination is a {@link java.io.Writer} 1094 * using this method would require UTF-8 decoding. 1095 * If so, implementation may instead choose to throw a 1096 * {@link UnsupportedOperationException} due to ineffectiveness 1097 * of having to decode input. 1098 */ writeRawUTF8String(byte[] text, int offset, int length)1099 public abstract void writeRawUTF8String(byte[] text, int offset, int length) 1100 throws IOException; 1101 1102 /** 1103 * Method similar to {@link #writeString(String)} but that takes as its input 1104 * a UTF-8 encoded String which has <b>not</b> been escaped using whatever 1105 * escaping scheme data format requires (for JSON that is backslash-escaping 1106 * for control characters and double-quotes; for other formats something else). 1107 * This means that textual JSON backends need to check if value needs 1108 * JSON escaping, but otherwise can just be copied as is to output. 1109 * Also, quoting that data format requires (like double-quotes for JSON) will be added 1110 * around the value if and as necessary. 1111 *<p> 1112 * Note that some backends may choose not to support this method: for 1113 * example, if underlying destination is a {@link java.io.Writer} 1114 * using this method would require UTF-8 decoding. 1115 * In this case 1116 * generator implementation may instead choose to throw a 1117 * {@link UnsupportedOperationException} due to ineffectiveness 1118 * of having to decode input. 1119 */ writeUTF8String(byte[] text, int offset, int length)1120 public abstract void writeUTF8String(byte[] text, int offset, int length) 1121 throws IOException; 1122 1123 /* 1124 /********************************************************** 1125 /* Public API, write methods, binary/raw content 1126 /********************************************************** 1127 */ 1128 1129 /** 1130 * Method that will force generator to copy 1131 * input text verbatim with <b>no</b> modifications (including 1132 * that no escaping is done and no separators are added even 1133 * if context [array, object] would otherwise require such). 1134 * If such separators are desired, use 1135 * {@link #writeRawValue(String)} instead. 1136 *<p> 1137 * Note that not all generator implementations necessarily support 1138 * such by-pass methods: those that do not will throw 1139 * {@link UnsupportedOperationException}. 1140 */ writeRaw(String text)1141 public abstract void writeRaw(String text) throws IOException; 1142 1143 /** 1144 * Method that will force generator to copy 1145 * input text verbatim with <b>no</b> modifications (including 1146 * that no escaping is done and no separators are added even 1147 * if context [array, object] would otherwise require such). 1148 * If such separators are desired, use 1149 * {@link #writeRawValue(String)} instead. 1150 *<p> 1151 * Note that not all generator implementations necessarily support 1152 * such by-pass methods: those that do not will throw 1153 * {@link UnsupportedOperationException}. 1154 */ writeRaw(String text, int offset, int len)1155 public abstract void writeRaw(String text, int offset, int len) throws IOException; 1156 1157 /** 1158 * Method that will force generator to copy 1159 * input text verbatim with <b>no</b> modifications (including 1160 * that no escaping is done and no separators are added even 1161 * if context [array, object] would otherwise require such). 1162 * If such separators are desired, use 1163 * {@link #writeRawValue(String)} instead. 1164 *<p> 1165 * Note that not all generator implementations necessarily support 1166 * such by-pass methods: those that do not will throw 1167 * {@link UnsupportedOperationException}. 1168 */ writeRaw(char[] text, int offset, int len)1169 public abstract void writeRaw(char[] text, int offset, int len) throws IOException; 1170 1171 /** 1172 * Method that will force generator to copy 1173 * input text verbatim with <b>no</b> modifications (including 1174 * that no escaping is done and no separators are added even 1175 * if context [array, object] would otherwise require such). 1176 * If such separators are desired, use 1177 * {@link #writeRawValue(String)} instead. 1178 *<p> 1179 * Note that not all generator implementations necessarily support 1180 * such by-pass methods: those that do not will throw 1181 * {@link UnsupportedOperationException}. 1182 */ writeRaw(char c)1183 public abstract void writeRaw(char c) throws IOException; 1184 1185 /** 1186 * Method that will force generator to copy 1187 * input text verbatim with <b>no</b> modifications (including 1188 * that no escaping is done and no separators are added even 1189 * if context [array, object] would otherwise require such). 1190 * If such separators are desired, use 1191 * {@link #writeRawValue(String)} instead. 1192 *<p> 1193 * Note that not all generator implementations necessarily support 1194 * such by-pass methods: those that do not will throw 1195 * {@link UnsupportedOperationException}. 1196 *<p> 1197 * The default implementation delegates to {@link #writeRaw(String)}; 1198 * other backends that support raw inclusion of text are encouraged 1199 * to implement it in more efficient manner (especially if they 1200 * use UTF-8 encoding). 1201 * 1202 * @since 2.1 1203 */ 1204 // public abstract void writeRaw(SerializableString raw) throws IOException; writeRaw(SerializableString raw)1205 public void writeRaw(SerializableString raw) throws IOException { 1206 writeRaw(raw.getValue()); 1207 } 1208 1209 /** 1210 * Method that will force generator to copy 1211 * input text verbatim without any modifications, but assuming 1212 * it must constitute a single legal JSON value (number, string, 1213 * boolean, null, Array or List). Assuming this, proper separators 1214 * are added if and as needed (comma or colon), and generator 1215 * state updated to reflect this. 1216 */ writeRawValue(String text)1217 public abstract void writeRawValue(String text) throws IOException; 1218 writeRawValue(String text, int offset, int len)1219 public abstract void writeRawValue(String text, int offset, int len) throws IOException; 1220 writeRawValue(char[] text, int offset, int len)1221 public abstract void writeRawValue(char[] text, int offset, int len) throws IOException; 1222 1223 /** 1224 * Method similar to {@link #writeRawValue(String)}, but potentially more 1225 * efficient as it may be able to use pre-encoded content (similar to 1226 * {@link #writeRaw(SerializableString)}. 1227 * 1228 * @since 2.5 1229 */ writeRawValue(SerializableString raw)1230 public void writeRawValue(SerializableString raw) throws IOException { 1231 writeRawValue(raw.getValue()); 1232 } 1233 1234 /** 1235 * Method that will output given chunk of binary data as base64 1236 * encoded, as a complete String value (surrounded by double quotes). 1237 * This method defaults 1238 *<p> 1239 * Note: because JSON Strings can not contain unescaped linefeeds, 1240 * if linefeeds are included (as per last argument), they must be 1241 * escaped. This adds overhead for decoding without improving 1242 * readability. 1243 * Alternatively if linefeeds are not included, 1244 * resulting String value may violate the requirement of base64 1245 * RFC which mandates line-length of 76 characters and use of 1246 * linefeeds. However, all {@link JsonParser} implementations 1247 * are required to accept such "long line base64"; as do 1248 * typical production-level base64 decoders. 1249 * 1250 * @param bv Base64 variant to use: defines details such as 1251 * whether padding is used (and if so, using which character); 1252 * what is the maximum line length before adding linefeed, 1253 * and also the underlying alphabet to use. 1254 */ writeBinary(Base64Variant bv, byte[] data, int offset, int len)1255 public abstract void writeBinary(Base64Variant bv, 1256 byte[] data, int offset, int len) throws IOException; 1257 1258 /** 1259 * Similar to {@link #writeBinary(Base64Variant,byte[],int,int)}, 1260 * but default to using the Jackson default Base64 variant 1261 * (which is {@link Base64Variants#MIME_NO_LINEFEEDS}). 1262 */ writeBinary(byte[] data, int offset, int len)1263 public void writeBinary(byte[] data, int offset, int len) throws IOException { 1264 writeBinary(Base64Variants.getDefaultVariant(), data, offset, len); 1265 } 1266 1267 /** 1268 * Similar to {@link #writeBinary(Base64Variant,byte[],int,int)}, 1269 * but assumes default to using the Jackson default Base64 variant 1270 * (which is {@link Base64Variants#MIME_NO_LINEFEEDS}). Also 1271 * assumes that whole byte array is to be output. 1272 */ writeBinary(byte[] data)1273 public void writeBinary(byte[] data) throws IOException { 1274 writeBinary(Base64Variants.getDefaultVariant(), data, 0, data.length); 1275 } 1276 1277 /** 1278 * Similar to {@link #writeBinary(Base64Variant,InputStream,int)}, 1279 * but assumes default to using the Jackson default Base64 variant 1280 * (which is {@link Base64Variants#MIME_NO_LINEFEEDS}). 1281 * 1282 * @param data InputStream to use for reading binary data to write. 1283 * Will not be closed after successful write operation 1284 * @param dataLength (optional) number of bytes that will be available; 1285 * or -1 to be indicate it is not known. Note that implementations 1286 * need not support cases where length is not known in advance; this 1287 * depends on underlying data format: JSON output does NOT require length, 1288 * other formats may 1289 */ writeBinary(InputStream data, int dataLength)1290 public int writeBinary(InputStream data, int dataLength) 1291 throws IOException { 1292 return writeBinary(Base64Variants.getDefaultVariant(), data, dataLength); 1293 } 1294 1295 /** 1296 * Method similar to {@link #writeBinary(Base64Variant,byte[],int,int)}, 1297 * but where input is provided through a stream, allowing for incremental 1298 * writes without holding the whole input in memory. 1299 * 1300 * @param bv Base64 variant to use 1301 * @param data InputStream to use for reading binary data to write. 1302 * Will not be closed after successful write operation 1303 * @param dataLength (optional) number of bytes that will be available; 1304 * or -1 to be indicate it is not known. 1305 * If a positive length is given, <code>data</code> MUST provide at least 1306 * that many bytes: if not, an exception will be thrown. 1307 * Note that implementations 1308 * need not support cases where length is not known in advance; this 1309 * depends on underlying data format: JSON output does NOT require length, 1310 * other formats may. 1311 * 1312 * @return Number of bytes read from <code>data</code> and written as binary payload 1313 * 1314 * @since 2.1 1315 */ writeBinary(Base64Variant bv, InputStream data, int dataLength)1316 public abstract int writeBinary(Base64Variant bv, 1317 InputStream data, int dataLength) throws IOException; 1318 1319 /* 1320 /********************************************************** 1321 /* Public API, write methods, numeric 1322 /********************************************************** 1323 */ 1324 1325 /** 1326 * Method for outputting given value as JSON number. 1327 * Can be called in any context where a value is expected 1328 * (Array value, Object field value, root-level value). 1329 * Additional white space may be added around the value 1330 * if pretty-printing is enabled. 1331 * 1332 * @param v Number value to write 1333 * 1334 * @since 2.2 1335 */ writeNumber(short v)1336 public void writeNumber(short v) throws IOException { writeNumber((int) v); } 1337 1338 /** 1339 * Method for outputting given value as JSON number. 1340 * Can be called in any context where a value is expected 1341 * (Array value, Object field value, root-level value). 1342 * Additional white space may be added around the value 1343 * if pretty-printing is enabled. 1344 * 1345 * @param v Number value to write 1346 */ writeNumber(int v)1347 public abstract void writeNumber(int v) throws IOException; 1348 1349 /** 1350 * Method for outputting given value as JSON number. 1351 * Can be called in any context where a value is expected 1352 * (Array value, Object field value, root-level value). 1353 * Additional white space may be added around the value 1354 * if pretty-printing is enabled. 1355 * 1356 * @param v Number value to write 1357 */ writeNumber(long v)1358 public abstract void writeNumber(long v) throws IOException; 1359 1360 /** 1361 * Method for outputting given value as JSON number. 1362 * Can be called in any context where a value is expected 1363 * (Array value, Object field value, root-level value). 1364 * Additional white space may be added around the value 1365 * if pretty-printing is enabled. 1366 * 1367 * @param v Number value to write 1368 */ writeNumber(BigInteger v)1369 public abstract void writeNumber(BigInteger v) throws IOException; 1370 1371 /** 1372 * Method for outputting indicate JSON numeric value. 1373 * Can be called in any context where a value is expected 1374 * (Array value, Object field value, root-level value). 1375 * Additional white space may be added around the value 1376 * if pretty-printing is enabled. 1377 * 1378 * @param v Number value to write 1379 */ writeNumber(double v)1380 public abstract void writeNumber(double v) throws IOException; 1381 1382 /** 1383 * Method for outputting indicate JSON numeric value. 1384 * Can be called in any context where a value is expected 1385 * (Array value, Object field value, root-level value). 1386 * Additional white space may be added around the value 1387 * if pretty-printing is enabled. 1388 * 1389 * @param v Number value to write 1390 */ writeNumber(float v)1391 public abstract void writeNumber(float v) throws IOException; 1392 1393 /** 1394 * Method for outputting indicate JSON numeric value. 1395 * Can be called in any context where a value is expected 1396 * (Array value, Object field value, root-level value). 1397 * Additional white space may be added around the value 1398 * if pretty-printing is enabled. 1399 * 1400 * @param v Number value to write 1401 */ writeNumber(BigDecimal v)1402 public abstract void writeNumber(BigDecimal v) throws IOException; 1403 1404 /** 1405 * Write method that can be used for custom numeric types that can 1406 * not be (easily?) converted to "standard" Java number types. 1407 * Because numbers are not surrounded by double quotes, regular 1408 * {@link #writeString} method can not be used; nor 1409 * {@link #writeRaw} because that does not properly handle 1410 * value separators needed in Array or Object contexts. 1411 *<p> 1412 * Note: because of lack of type safety, some generator 1413 * implementations may not be able to implement this 1414 * method. For example, if a binary JSON format is used, 1415 * it may require type information for encoding; similarly 1416 * for generator-wrappers around Java objects or JSON nodes. 1417 * If implementation does not implement this method, 1418 * it needs to throw {@link UnsupportedOperationException}. 1419 * 1420 * @throws UnsupportedOperationException If underlying data format does not 1421 * support numbers serialized textually AND if generator is not allowed 1422 * to just output a String instead (Schema-based formats may require actual 1423 * number, for example) 1424 */ writeNumber(String encodedValue)1425 public abstract void writeNumber(String encodedValue) throws IOException; 1426 1427 /** 1428 * Overloaded version of {@link #writeNumber(String)} with same semantics 1429 * but possibly more efficient operation. 1430 * 1431 * @since 2.11 1432 */ writeNumber(char[] encodedValueBuffer, int offset, int length)1433 public void writeNumber(char[] encodedValueBuffer, int offset, int length) throws IOException { 1434 writeNumber(new String(encodedValueBuffer, offset, length)); 1435 } 1436 1437 /* 1438 /********************************************************** 1439 /* Public API, write methods, other value types 1440 /********************************************************** 1441 */ 1442 1443 /** 1444 * Method for outputting literal JSON boolean value (one of 1445 * Strings 'true' and 'false'). 1446 * Can be called in any context where a value is expected 1447 * (Array value, Object field value, root-level value). 1448 * Additional white space may be added around the value 1449 * if pretty-printing is enabled. 1450 */ writeBoolean(boolean state)1451 public abstract void writeBoolean(boolean state) throws IOException; 1452 1453 /** 1454 * Method for outputting literal JSON null value. 1455 * Can be called in any context where a value is expected 1456 * (Array value, Object field value, root-level value). 1457 * Additional white space may be added around the value 1458 * if pretty-printing is enabled. 1459 */ writeNull()1460 public abstract void writeNull() throws IOException; 1461 1462 /** 1463 * Method that can be called on backends that support passing opaque datatypes of 1464 * non-JSON formats 1465 * 1466 * @since 2.8 1467 */ writeEmbeddedObject(Object object)1468 public void writeEmbeddedObject(Object object) throws IOException { 1469 // 01-Sep-2016, tatu: As per [core#318], handle small number of cases 1470 if (object == null) { 1471 writeNull(); 1472 return; 1473 } 1474 if (object instanceof byte[]) { 1475 writeBinary((byte[]) object); 1476 return; 1477 } 1478 throw new JsonGenerationException("No native support for writing embedded objects of type " 1479 +object.getClass().getName(), 1480 this); 1481 } 1482 1483 /* 1484 /********************************************************** 1485 /* Public API, write methods, Native Ids (type, object) 1486 /********************************************************** 1487 */ 1488 1489 /** 1490 * Method that can be called to output so-called native Object Id. 1491 * Note that it may only be called after ensuring this is legal 1492 * (with {@link #canWriteObjectId()}), as not all data formats 1493 * have native type id support; and some may only allow them in 1494 * certain positions or locations. 1495 * If output is not allowed by the data format in this position, 1496 * a {@link JsonGenerationException} will be thrown. 1497 * 1498 * @since 2.3 1499 */ writeObjectId(Object id)1500 public void writeObjectId(Object id) throws IOException { 1501 throw new JsonGenerationException("No native support for writing Object Ids", this); 1502 } 1503 1504 /** 1505 * Method that can be called to output references to native Object Ids. 1506 * Note that it may only be called after ensuring this is legal 1507 * (with {@link #canWriteObjectId()}), as not all data formats 1508 * have native type id support; and some may only allow them in 1509 * certain positions or locations. 1510 * If output is not allowed by the data format in this position, 1511 * a {@link JsonGenerationException} will be thrown. 1512 */ writeObjectRef(Object id)1513 public void writeObjectRef(Object id) throws IOException { 1514 throw new JsonGenerationException("No native support for writing Object Ids", this); 1515 } 1516 1517 /** 1518 * Method that can be called to output so-called native Type Id. 1519 * Note that it may only be called after ensuring this is legal 1520 * (with {@link #canWriteTypeId()}), as not all data formats 1521 * have native type id support; and some may only allow them in 1522 * certain positions or locations. 1523 * If output is not allowed by the data format in this position, 1524 * a {@link JsonGenerationException} will be thrown. 1525 * 1526 * @since 2.3 1527 */ writeTypeId(Object id)1528 public void writeTypeId(Object id) throws IOException { 1529 throw new JsonGenerationException("No native support for writing Type Ids", this); 1530 } 1531 1532 /* 1533 * Replacement method for {@link #writeTypeId(Object)} which is called 1534 * regardless of whether format has native type ids. If it does have native 1535 * type ids, those are to be used (if configuration allows this), if not, 1536 * structural type id inclusion is to be used. For JSON, for example, no 1537 * native type ids exist and structural inclusion is always used. 1538 *<p> 1539 * NOTE: databind may choose to skip calling this method for some special cases 1540 * (and instead included type id via regular write methods and/or {@link #writeTypeId} 1541 * -- this is discouraged, but not illegal, and may be necessary as a work-around 1542 * in some cases. 1543 * 1544 * @since 2.9 1545 */ writeTypePrefix(WritableTypeId typeIdDef)1546 public WritableTypeId writeTypePrefix(WritableTypeId typeIdDef) throws IOException 1547 { 1548 Object id = typeIdDef.id; 1549 1550 final JsonToken valueShape = typeIdDef.valueShape; 1551 if (canWriteTypeId()) { 1552 typeIdDef.wrapperWritten = false; 1553 // just rely on native type output method (sub-classes likely to override) 1554 writeTypeId(id); 1555 } else { 1556 // No native type id; write wrappers 1557 // Normally we only support String type ids (non-String reserved for native type ids) 1558 String idStr = (id instanceof String) ? (String) id : String.valueOf(id); 1559 typeIdDef.wrapperWritten = true; 1560 1561 Inclusion incl = typeIdDef.include; 1562 // first: can not output "as property" if value not Object; if so, must do "as array" 1563 if ((valueShape != JsonToken.START_OBJECT) 1564 && incl.requiresObjectContext()) { 1565 typeIdDef.include = incl = WritableTypeId.Inclusion.WRAPPER_ARRAY; 1566 } 1567 1568 switch (incl) { 1569 case PARENT_PROPERTY: 1570 // nothing to do here, as it has to be written in suffix... 1571 break; 1572 case PAYLOAD_PROPERTY: 1573 // only output as native type id; otherwise caller must handle using some 1574 // other mechanism, so... 1575 break; 1576 case METADATA_PROPERTY: 1577 // must have Object context by now, so simply write as field name 1578 // Note, too, that it's bit tricky, since we must print START_OBJECT that is part 1579 // of value first -- and then NOT output it later on: hence return "early" 1580 writeStartObject(typeIdDef.forValue); 1581 writeStringField(typeIdDef.asProperty, idStr); 1582 return typeIdDef; 1583 1584 case WRAPPER_OBJECT: 1585 // NOTE: this is wrapper, not directly related to value to output, so don't pass 1586 writeStartObject(); 1587 writeFieldName(idStr); 1588 break; 1589 case WRAPPER_ARRAY: 1590 default: // should never occur but translate as "as-array" 1591 writeStartArray(); // wrapper, not actual array object to write 1592 writeString(idStr); 1593 } 1594 } 1595 // and finally possible start marker for value itself: 1596 if (valueShape == JsonToken.START_OBJECT) { 1597 writeStartObject(typeIdDef.forValue); 1598 } else if (valueShape == JsonToken.START_ARRAY) { 1599 // should we now set the current object? 1600 writeStartArray(); 1601 } 1602 return typeIdDef; 1603 } 1604 1605 /* 1606 * @since 2.9 1607 */ writeTypeSuffix(WritableTypeId typeIdDef)1608 public WritableTypeId writeTypeSuffix(WritableTypeId typeIdDef) throws IOException 1609 { 1610 final JsonToken valueShape = typeIdDef.valueShape; 1611 // First: does value need closing? 1612 if (valueShape == JsonToken.START_OBJECT) { 1613 writeEndObject(); 1614 } else if (valueShape == JsonToken.START_ARRAY) { 1615 writeEndArray(); 1616 } 1617 1618 if (typeIdDef.wrapperWritten) { 1619 switch (typeIdDef.include) { 1620 case WRAPPER_ARRAY: 1621 writeEndArray(); 1622 break; 1623 case PARENT_PROPERTY: 1624 // unusually, need to output AFTER value. And no real wrapper... 1625 { 1626 Object id = typeIdDef.id; 1627 String idStr = (id instanceof String) ? (String) id : String.valueOf(id); 1628 writeStringField(typeIdDef.asProperty, idStr); 1629 } 1630 break; 1631 case METADATA_PROPERTY: 1632 case PAYLOAD_PROPERTY: 1633 // no actual wrapper; included within Object itself 1634 break; 1635 case WRAPPER_OBJECT: 1636 default: // should never occur but... 1637 writeEndObject(); 1638 break; 1639 } 1640 } 1641 return typeIdDef; 1642 } 1643 1644 /* 1645 /********************************************************** 1646 /* Public API, write methods, serializing Java objects 1647 /********************************************************** 1648 */ 1649 1650 /** 1651 * Method for writing given Java object (POJO) as Json. 1652 * Exactly how the object gets written depends on object 1653 * in question (ad on codec, its configuration); for most 1654 * beans it will result in JSON Object, but for others JSON 1655 * Array, or String or numeric value (and for nulls, JSON 1656 * null literal. 1657 * <b>NOTE</b>: generator must have its <b>object codec</b> 1658 * set to non-null value; for generators created by a mapping 1659 * factory this is the case, for others not. 1660 */ writeObject(Object pojo)1661 public abstract void writeObject(Object pojo) throws IOException; 1662 1663 /** 1664 * Method for writing given JSON tree (expressed as a tree 1665 * where given JsonNode is the root) using this generator. 1666 * This will generally just call 1667 * {@link #writeObject} with given node, but is added 1668 * for convenience and to make code more explicit in cases 1669 * where it deals specifically with trees. 1670 */ writeTree(TreeNode rootNode)1671 public abstract void writeTree(TreeNode rootNode) throws IOException; 1672 1673 /* 1674 /********************************************************** 1675 /* Public API, convenience field write methods 1676 /********************************************************** 1677 */ 1678 1679 // 04-Oct-2019, tatu: Reminder: these could be defined final to 1680 // remember NOT to override in delegating sub-classes -- but 1681 // not final in 2.x to reduce compatibility issues 1682 1683 /** 1684 * Convenience method for outputting a field entry ("member") 1685 * that contains specified data in base64-encoded form. 1686 * Equivalent to: 1687 *<pre> 1688 * writeFieldName(fieldName); 1689 * writeBinary(value); 1690 *</pre> 1691 */ writeBinaryField(String fieldName, byte[] data)1692 public void writeBinaryField(String fieldName, byte[] data) throws IOException { 1693 writeFieldName(fieldName); 1694 writeBinary(data); 1695 } 1696 1697 /** 1698 * Convenience method for outputting a field entry ("member") 1699 * that has a boolean value. Equivalent to: 1700 *<pre> 1701 * writeFieldName(fieldName); 1702 * writeBoolean(value); 1703 *</pre> 1704 */ writeBooleanField(String fieldName, boolean value)1705 public void writeBooleanField(String fieldName, boolean value) throws IOException { 1706 writeFieldName(fieldName); 1707 writeBoolean(value); 1708 } 1709 1710 /** 1711 * Convenience method for outputting a field entry ("member") 1712 * that has JSON literal value null. Equivalent to: 1713 *<pre> 1714 * writeFieldName(fieldName); 1715 * writeNull(); 1716 *</pre> 1717 */ writeNullField(String fieldName)1718 public void writeNullField(String fieldName) throws IOException { 1719 writeFieldName(fieldName); 1720 writeNull(); 1721 } 1722 1723 /** 1724 * Convenience method for outputting a field entry ("member") 1725 * that has a String value. Equivalent to: 1726 *<pre> 1727 * writeFieldName(fieldName); 1728 * writeString(value); 1729 *</pre> 1730 *<p> 1731 * Note: many performance-sensitive implementations override this method 1732 */ writeStringField(String fieldName, String value)1733 public void writeStringField(String fieldName, String value) throws IOException { 1734 writeFieldName(fieldName); 1735 writeString(value); 1736 } 1737 1738 /** 1739 * Convenience method for outputting a field entry ("member") 1740 * that has the specified numeric value. Equivalent to: 1741 *<pre> 1742 * writeFieldName(fieldName); 1743 * writeNumber(value); 1744 *</pre> 1745 * 1746 * @since 2.11 1747 */ writeNumberField(String fieldName, short value)1748 public void writeNumberField(String fieldName, short value) throws IOException { 1749 writeFieldName(fieldName); 1750 writeNumber(value); 1751 } 1752 1753 /** 1754 * Convenience method for outputting a field entry ("member") 1755 * that has the specified numeric value. Equivalent to: 1756 *<pre> 1757 * writeFieldName(fieldName); 1758 * writeNumber(value); 1759 *</pre> 1760 */ writeNumberField(String fieldName, int value)1761 public void writeNumberField(String fieldName, int value) throws IOException { 1762 writeFieldName(fieldName); 1763 writeNumber(value); 1764 } 1765 1766 /** 1767 * Convenience method for outputting a field entry ("member") 1768 * that has the specified numeric value. Equivalent to: 1769 *<pre> 1770 * writeFieldName(fieldName); 1771 * writeNumber(value); 1772 *</pre> 1773 */ writeNumberField(String fieldName, long value)1774 public void writeNumberField(String fieldName, long value) throws IOException { 1775 writeFieldName(fieldName); 1776 writeNumber(value); 1777 } 1778 1779 /** 1780 * Convenience method for outputting a field entry ("member") 1781 * that has the specified numeric value. Equivalent to: 1782 *<pre> 1783 * writeFieldName(fieldName); 1784 * writeNumber(value); 1785 *</pre> 1786 * 1787 * @since 2.11 1788 */ writeNumberField(String fieldName, BigInteger value)1789 public void writeNumberField(String fieldName, BigInteger value) throws IOException { 1790 writeFieldName(fieldName); 1791 writeNumber(value); 1792 } 1793 1794 /** 1795 * Convenience method for outputting a field entry ("member") 1796 * that has the specified numeric value. Equivalent to: 1797 *<pre> 1798 * writeFieldName(fieldName); 1799 * writeNumber(value); 1800 *</pre> 1801 */ writeNumberField(String fieldName, float value)1802 public void writeNumberField(String fieldName, float value) throws IOException { 1803 writeFieldName(fieldName); 1804 writeNumber(value); 1805 } 1806 1807 /** 1808 * Convenience method for outputting a field entry ("member") 1809 * that has the specified numeric value. Equivalent to: 1810 *<pre> 1811 * writeFieldName(fieldName); 1812 * writeNumber(value); 1813 *</pre> 1814 */ writeNumberField(String fieldName, double value)1815 public void writeNumberField(String fieldName, double value) throws IOException { 1816 writeFieldName(fieldName); 1817 writeNumber(value); 1818 } 1819 1820 /** 1821 * Convenience method for outputting a field entry ("member") 1822 * that has the specified numeric value. 1823 * Equivalent to: 1824 *<pre> 1825 * writeFieldName(fieldName); 1826 * writeNumber(value); 1827 *</pre> 1828 */ writeNumberField(String fieldName, BigDecimal value)1829 public void writeNumberField(String fieldName, BigDecimal value) throws IOException { 1830 writeFieldName(fieldName); 1831 writeNumber(value); 1832 } 1833 1834 /** 1835 * Convenience method for outputting a field entry ("member") 1836 * (that will contain a JSON Array value), and the START_ARRAY marker. 1837 * Equivalent to: 1838 *<pre> 1839 * writeFieldName(fieldName); 1840 * writeStartArray(); 1841 *</pre> 1842 *<p> 1843 * Note: caller still has to take care to close the array 1844 * (by calling {#link #writeEndArray}) after writing all values 1845 * of the value Array. 1846 */ writeArrayFieldStart(String fieldName)1847 public void writeArrayFieldStart(String fieldName) throws IOException { 1848 writeFieldName(fieldName); 1849 writeStartArray(); 1850 } 1851 1852 /** 1853 * Convenience method for outputting a field entry ("member") 1854 * (that will contain an Object value), and the START_OBJECT marker. 1855 * Equivalent to: 1856 *<pre> 1857 * writeFieldName(fieldName); 1858 * writeStartObject(); 1859 *</pre> 1860 *<p> 1861 * Note: caller still has to take care to close the Object 1862 * (by calling {#link #writeEndObject}) after writing all 1863 * entries of the value Object. 1864 */ writeObjectFieldStart(String fieldName)1865 public void writeObjectFieldStart(String fieldName) throws IOException { 1866 writeFieldName(fieldName); 1867 writeStartObject(); 1868 } 1869 1870 /** 1871 * Convenience method for outputting a field entry ("member") 1872 * that has contents of specific Java object as its value. 1873 * Equivalent to: 1874 *<pre> 1875 * writeFieldName(fieldName); 1876 * writeObject(pojo); 1877 *</pre> 1878 */ writeObjectField(String fieldName, Object pojo)1879 public void writeObjectField(String fieldName, Object pojo) throws IOException { 1880 writeFieldName(fieldName); 1881 writeObject(pojo); 1882 } 1883 1884 // // // But this method does need to be delegate so... 1885 1886 /** 1887 * Method called to indicate that a property in this position was 1888 * skipped. It is usually only called for generators that return 1889 * <code>false</code> from {@link #canOmitFields()}. 1890 *<p> 1891 * Default implementation does nothing. 1892 * 1893 * @since 2.3 1894 */ writeOmittedField(String fieldName)1895 public void writeOmittedField(String fieldName) throws IOException { } 1896 1897 /* 1898 /********************************************************** 1899 /* Public API, copy-through methods 1900 /********************************************************** 1901 */ 1902 1903 /** 1904 * Method for copying contents of the current event that 1905 * the given parser instance points to. 1906 * Note that the method <b>will not</b> copy any other events, 1907 * such as events contained within JSON Array or Object structures. 1908 *<p> 1909 * Calling this method will not advance the given 1910 * parser, although it may cause parser to internally process 1911 * more data (if it lazy loads contents of value events, for example) 1912 */ copyCurrentEvent(JsonParser p)1913 public void copyCurrentEvent(JsonParser p) throws IOException 1914 { 1915 JsonToken t = p.currentToken(); 1916 final int token = (t == null) ? ID_NOT_AVAILABLE : t.id(); 1917 switch (token) { 1918 case ID_NOT_AVAILABLE: 1919 _reportError("No current event to copy"); 1920 break; // never gets here 1921 case ID_START_OBJECT: 1922 writeStartObject(); 1923 break; 1924 case ID_END_OBJECT: 1925 writeEndObject(); 1926 break; 1927 case ID_START_ARRAY: 1928 writeStartArray(); 1929 break; 1930 case ID_END_ARRAY: 1931 writeEndArray(); 1932 break; 1933 case ID_FIELD_NAME: 1934 writeFieldName(p.getCurrentName()); 1935 break; 1936 case ID_STRING: 1937 if (p.hasTextCharacters()) { 1938 writeString(p.getTextCharacters(), p.getTextOffset(), p.getTextLength()); 1939 } else { 1940 writeString(p.getText()); 1941 } 1942 break; 1943 case ID_NUMBER_INT: 1944 { 1945 NumberType n = p.getNumberType(); 1946 if (n == NumberType.INT) { 1947 writeNumber(p.getIntValue()); 1948 } else if (n == NumberType.BIG_INTEGER) { 1949 writeNumber(p.getBigIntegerValue()); 1950 } else { 1951 writeNumber(p.getLongValue()); 1952 } 1953 break; 1954 } 1955 case ID_NUMBER_FLOAT: 1956 { 1957 NumberType n = p.getNumberType(); 1958 if (n == NumberType.BIG_DECIMAL) { 1959 writeNumber(p.getDecimalValue()); 1960 } else if (n == NumberType.FLOAT) { 1961 writeNumber(p.getFloatValue()); 1962 } else { 1963 writeNumber(p.getDoubleValue()); 1964 } 1965 break; 1966 } 1967 case ID_TRUE: 1968 writeBoolean(true); 1969 break; 1970 case ID_FALSE: 1971 writeBoolean(false); 1972 break; 1973 case ID_NULL: 1974 writeNull(); 1975 break; 1976 case ID_EMBEDDED_OBJECT: 1977 writeObject(p.getEmbeddedObject()); 1978 break; 1979 default: 1980 throw new IllegalStateException("Internal error: unknown current token, "+t); 1981 } 1982 } 1983 1984 /** 1985 * Method for copying contents of the current event 1986 * <b>and following events that it encloses</b> 1987 * the given parser instance points to. 1988 *<p> 1989 * So what constitutes enclosing? Here is the list of 1990 * events that have associated enclosed events that will 1991 * get copied: 1992 *<ul> 1993 * <li>{@link JsonToken#START_OBJECT}: 1994 * all events up to and including matching (closing) 1995 * {@link JsonToken#END_OBJECT} will be copied 1996 * </li> 1997 * <li>{@link JsonToken#START_ARRAY} 1998 * all events up to and including matching (closing) 1999 * {@link JsonToken#END_ARRAY} will be copied 2000 * </li> 2001 * <li>{@link JsonToken#FIELD_NAME} the logical value (which 2002 * can consist of a single scalar value; or a sequence of related 2003 * events for structured types (JSON Arrays, Objects)) will 2004 * be copied along with the name itself. So essentially the 2005 * whole <b>field entry</b> (name and value) will be copied. 2006 * </li> 2007 *</ul> 2008 *<p> 2009 * After calling this method, parser will point to the 2010 * <b>last event</b> that was copied. This will either be 2011 * the event parser already pointed to (if there were no 2012 * enclosed events), or the last enclosed event copied. 2013 */ copyCurrentStructure(JsonParser p)2014 public void copyCurrentStructure(JsonParser p) throws IOException 2015 { 2016 JsonToken t = p.currentToken(); 2017 // Let's handle field-name separately first 2018 int id = (t == null) ? ID_NOT_AVAILABLE : t.id(); 2019 if (id == ID_FIELD_NAME) { 2020 writeFieldName(p.getCurrentName()); 2021 t = p.nextToken(); 2022 id = (t == null) ? ID_NOT_AVAILABLE : t.id(); 2023 // fall-through to copy the associated value 2024 } 2025 switch (id) { 2026 case ID_START_OBJECT: 2027 writeStartObject(); 2028 _copyCurrentContents(p); 2029 return; 2030 case ID_START_ARRAY: 2031 writeStartArray(); 2032 _copyCurrentContents(p); 2033 return; 2034 2035 default: 2036 copyCurrentEvent(p); 2037 } 2038 } 2039 2040 /** 2041 * @since 2.10 2042 */ _copyCurrentContents(JsonParser p)2043 protected void _copyCurrentContents(JsonParser p) throws IOException 2044 { 2045 int depth = 1; 2046 JsonToken t; 2047 2048 // Mostly copied from `copyCurrentEvent()`, but with added nesting counts 2049 while ((t = p.nextToken()) != null) { 2050 switch (t.id()) { 2051 case ID_FIELD_NAME: 2052 writeFieldName(p.getCurrentName()); 2053 break; 2054 2055 case ID_START_ARRAY: 2056 writeStartArray(); 2057 ++depth; 2058 break; 2059 2060 case ID_START_OBJECT: 2061 writeStartObject(); 2062 ++depth; 2063 break; 2064 2065 case ID_END_ARRAY: 2066 writeEndArray(); 2067 if (--depth == 0) { 2068 return; 2069 } 2070 break; 2071 case ID_END_OBJECT: 2072 writeEndObject(); 2073 if (--depth == 0) { 2074 return; 2075 } 2076 break; 2077 2078 case ID_STRING: 2079 if (p.hasTextCharacters()) { 2080 writeString(p.getTextCharacters(), p.getTextOffset(), p.getTextLength()); 2081 } else { 2082 writeString(p.getText()); 2083 } 2084 break; 2085 case ID_NUMBER_INT: 2086 { 2087 NumberType n = p.getNumberType(); 2088 if (n == NumberType.INT) { 2089 writeNumber(p.getIntValue()); 2090 } else if (n == NumberType.BIG_INTEGER) { 2091 writeNumber(p.getBigIntegerValue()); 2092 } else { 2093 writeNumber(p.getLongValue()); 2094 } 2095 break; 2096 } 2097 case ID_NUMBER_FLOAT: 2098 { 2099 NumberType n = p.getNumberType(); 2100 if (n == NumberType.BIG_DECIMAL) { 2101 writeNumber(p.getDecimalValue()); 2102 } else if (n == NumberType.FLOAT) { 2103 writeNumber(p.getFloatValue()); 2104 } else { 2105 writeNumber(p.getDoubleValue()); 2106 } 2107 break; 2108 } 2109 case ID_TRUE: 2110 writeBoolean(true); 2111 break; 2112 case ID_FALSE: 2113 writeBoolean(false); 2114 break; 2115 case ID_NULL: 2116 writeNull(); 2117 break; 2118 case ID_EMBEDDED_OBJECT: 2119 writeObject(p.getEmbeddedObject()); 2120 break; 2121 default: 2122 throw new IllegalStateException("Internal error: unknown current token, "+t); 2123 } 2124 } 2125 } 2126 2127 /* 2128 /********************************************************** 2129 /* Public API, context access 2130 /********************************************************** 2131 */ 2132 2133 /** 2134 * @return Context object that can give information about logical 2135 * position within generated json content. 2136 */ getOutputContext()2137 public abstract JsonStreamContext getOutputContext(); 2138 2139 /* 2140 /********************************************************** 2141 /* Public API, buffer handling 2142 /********************************************************** 2143 */ 2144 2145 /** 2146 * Method called to flush any buffered content to the underlying 2147 * target (output stream, writer), and to flush the target itself 2148 * as well. 2149 */ 2150 @Override flush()2151 public abstract void flush() throws IOException; 2152 2153 /** 2154 * Method that can be called to determine whether this generator 2155 * is closed or not. If it is closed, no more output can be done. 2156 */ isClosed()2157 public abstract boolean isClosed(); 2158 2159 /* 2160 /********************************************************** 2161 /* Closeable implementation 2162 /********************************************************** 2163 */ 2164 2165 /** 2166 * Method called to close this generator, so that no more content 2167 * can be written. 2168 *<p> 2169 * Whether the underlying target (stream, writer) gets closed depends 2170 * on whether this generator either manages the target (i.e. is the 2171 * only one with access to the target -- case if caller passes a 2172 * reference to the resource such as File, but not stream); or 2173 * has feature {@link Feature#AUTO_CLOSE_TARGET} enabled. 2174 * If either of above is true, the target is also closed. Otherwise 2175 * (not managing, feature not enabled), target is not closed. 2176 */ 2177 @Override close()2178 public abstract void close() throws IOException; 2179 2180 /* 2181 /********************************************************** 2182 /* Helper methods for sub-classes 2183 /********************************************************** 2184 */ 2185 2186 /** 2187 * Helper method used for constructing and throwing 2188 * {@link JsonGenerationException} with given base message. 2189 *<p> 2190 * Note that sub-classes may override this method to add more detail 2191 * or use a {@link JsonGenerationException} sub-class. 2192 */ _reportError(String msg)2193 protected void _reportError(String msg) throws JsonGenerationException { 2194 throw new JsonGenerationException(msg, this); 2195 } 2196 _throwInternal()2197 protected final void _throwInternal() { VersionUtil.throwInternal(); } 2198 _reportUnsupportedOperation()2199 protected void _reportUnsupportedOperation() { 2200 throw new UnsupportedOperationException("Operation not supported by generator of type "+getClass().getName()); 2201 } 2202 2203 /** 2204 * @since 2.8 2205 */ _verifyOffsets(int arrayLength, int offset, int length)2206 protected final void _verifyOffsets(int arrayLength, int offset, int length) 2207 { 2208 if ((offset < 0) || (offset + length) > arrayLength) { 2209 throw new IllegalArgumentException(String.format( 2210 "invalid argument(s) (offset=%d, length=%d) for input array of %d element", 2211 offset, length, arrayLength)); 2212 } 2213 } 2214 2215 /** 2216 * Helper method to try to call appropriate write method for given 2217 * untyped Object. At this point, no structural conversions should be done, 2218 * only simple basic types are to be coerced as necessary. 2219 * 2220 * @param value Non-null value to write 2221 */ _writeSimpleObject(Object value)2222 protected void _writeSimpleObject(Object value) throws IOException 2223 { 2224 // 31-Dec-2009, tatu: Actually, we could just handle some basic 2225 // types even without codec. This can improve interoperability, 2226 // and specifically help with TokenBuffer. 2227 if (value == null) { 2228 writeNull(); 2229 return; 2230 } 2231 if (value instanceof String) { 2232 writeString((String) value); 2233 return; 2234 } 2235 if (value instanceof Number) { 2236 Number n = (Number) value; 2237 if (n instanceof Integer) { 2238 writeNumber(n.intValue()); 2239 return; 2240 } else if (n instanceof Long) { 2241 writeNumber(n.longValue()); 2242 return; 2243 } else if (n instanceof Double) { 2244 writeNumber(n.doubleValue()); 2245 return; 2246 } else if (n instanceof Float) { 2247 writeNumber(n.floatValue()); 2248 return; 2249 } else if (n instanceof Short) { 2250 writeNumber(n.shortValue()); 2251 return; 2252 } else if (n instanceof Byte) { 2253 writeNumber(n.byteValue()); 2254 return; 2255 } else if (n instanceof BigInteger) { 2256 writeNumber((BigInteger) n); 2257 return; 2258 } else if (n instanceof BigDecimal) { 2259 writeNumber((BigDecimal) n); 2260 return; 2261 2262 // then Atomic types 2263 } else if (n instanceof AtomicInteger) { 2264 writeNumber(((AtomicInteger) n).get()); 2265 return; 2266 } else if (n instanceof AtomicLong) { 2267 writeNumber(((AtomicLong) n).get()); 2268 return; 2269 } 2270 } else if (value instanceof byte[]) { 2271 writeBinary((byte[]) value); 2272 return; 2273 } else if (value instanceof Boolean) { 2274 writeBoolean((Boolean) value); 2275 return; 2276 } else if (value instanceof AtomicBoolean) { 2277 writeBoolean(((AtomicBoolean) value).get()); 2278 return; 2279 } 2280 throw new IllegalStateException("No ObjectCodec defined for the generator, can only serialize simple wrapper types (type passed " 2281 +value.getClass().getName()+")"); 2282 } 2283 } 2284