1 package com.fasterxml.jackson.core.type; 2 3 import com.fasterxml.jackson.core.JsonToken; 4 5 /** 6 * This is a simple value class used between core streaming and higher level 7 * databinding to pass information about type ids to write. 8 * Properties are exposed and mutable on purpose: they are only used for communication 9 * over serialization of a single value, and neither retained across calls nor shared 10 * between threads. 11 *<p> 12 * Usual usage pattern is such that instance of this class is passed on two calls that are 13 * needed for outputting type id (and possible additional wrapping, depending on format; 14 * JSON, for example, requires wrapping as type id is part of regular data): first, a "prefix" 15 * write (which usually includes actual id), performed before value write; and then 16 * matching "suffix" write after value serialization. 17 * 18 * @since 2.9 19 */ 20 public class WritableTypeId 21 { 22 /** 23 * Enumeration of values that matches enum `As` from annotation 24 * `JsonTypeInfo`: separate definition to avoid dependency between 25 * streaming core and annotations packages; also allows more flexibility 26 * in case new values needed at this level of internal API. 27 *<p> 28 * NOTE: in most cases this only matters with formats that do NOT have native 29 * type id capabilities, and require type id to be included within regular 30 * data (whether exposed as Java properties or not). Formats with native 31 * types usually use native type id functionality regardless, unless 32 * overridden by a feature to use "non-native" type inclusion. 33 */ 34 public enum Inclusion { 35 /** 36 * Inclusion as wrapper Array (1st element type id, 2nd element value). 37 *<p> 38 * Corresponds to <code>JsonTypeInfo.As.WRAPPER_ARRAY</code>. 39 */ 40 WRAPPER_ARRAY, 41 42 /** 43 * Inclusion as wrapper Object that has one key/value pair where type id 44 * is the key for typed value. 45 *<p> 46 * Corresponds to <code>JsonTypeInfo.As.WRAPPER_OBJECT</code>. 47 */ 48 WRAPPER_OBJECT, 49 50 /** 51 * Inclusion as a property within Object to write, but logically as separate 52 * metadata that is not exposed as payload to caller: that is, does not match 53 * any of visible properties value object has. 54 *<p> 55 * NOTE: if shape of typed value to write is NOT Object, will instead use 56 * {@link #WRAPPER_ARRAY} inclusion. 57 *<p> 58 * Corresponds to <code>JsonTypeInfo.As.PROPERTY</code>. 59 */ 60 METADATA_PROPERTY, 61 62 /** 63 * Inclusion as a "regular" property within Object to write; this implies that 64 * its value should come from regular POJO property on serialization, and 65 * be deserialized into such property. This handling, however, is up to databinding. 66 *<p> 67 * Regarding handling, type id is ONLY written as native type id; if no native 68 * type ids available, caller is assumed to handle output some other way. 69 * This is different from {@link #METADATA_PROPERTY}. 70 *<p> 71 * NOTE: if shape of typed value to write is NOT Object, will instead use 72 * {@link #WRAPPER_ARRAY} inclusion. 73 *<p> 74 * Corresponds to <code>JsonTypeInfo.As.EXISTING_PROPERTY</code>. 75 */ 76 PAYLOAD_PROPERTY, 77 78 /** 79 * Inclusion as a property within "parent" Object of value Object to write. 80 * This typically requires slightly convoluted processing in which property 81 * that contains type id is actually written <b>after</b> typed value object 82 * itself is written. 83 *<br> 84 * Note that it is illegal to call write method if the current (parent) write context 85 * is not Object: no coercion is done for other inclusion types (unlike with 86 * other <code>xxx_PROPERTY</code> choices. 87 * This also means that root values MAY NOT use this type id inclusion mechanism 88 * (as they have no parent context). 89 *<p> 90 * Corresponds to <code>JsonTypeInfo.As.EXTERNAL_PROPERTY</code>. 91 */ 92 PARENT_PROPERTY; 93 requiresObjectContext()94 public boolean requiresObjectContext() { 95 return (this == METADATA_PROPERTY) || (this == PAYLOAD_PROPERTY); 96 } 97 } 98 99 /** 100 * Java object for which type id is being written. Not needed by default handling, 101 * but may be useful for customized format handling. 102 */ 103 public Object forValue; 104 105 /** 106 * (optional) Super-type of {@link #forValue} to use for type id generation (if no 107 * explicit id passed): used instead of actual class of {@link #forValue} in cases 108 * where we do not want to use the "real" type but something more generic, usually 109 * to work around specific problem with implementation type, or its deserializer. 110 */ 111 public Class<?> forValueType; 112 113 /** 114 * Actual type id to use: usually {link java.lang.String}. 115 */ 116 public Object id; 117 118 /** 119 * If type id is to be embedded as a regular property, name of the property; 120 * otherwise `null`. 121 *<p> 122 * NOTE: if "wrap-as-Object" is used, this does NOT contain property name to 123 * use but `null`. 124 */ 125 public String asProperty; 126 127 /** 128 * Property used to indicate style of inclusion for this type id, in cases where 129 * no native type id may be used (either because format has none, like JSON; or 130 * because use of native type ids is disabled [with YAML]). 131 */ 132 public Inclusion include; 133 134 /** 135 * Information about intended shape of the value being written (that is, {@link #forValue}); 136 * in case of structured values, start token of the structure; for scalars, value token. 137 * Main difference is between structured values 138 * ({@link JsonToken#START_ARRAY}, {@link JsonToken#START_OBJECT}) 139 * and scalars ({@link JsonToken#VALUE_STRING}): specific scalar type may not be 140 * important for processing. 141 */ 142 public JsonToken valueShape; 143 144 /** 145 * Flag that can be set to indicate that wrapper structure was written (during 146 * prefix-writing); used to determine if suffix requires matching close markers. 147 */ 148 public boolean wrapperWritten; 149 150 /** 151 * Optional additional information that generator may add during "prefix write", 152 * to be available on matching "suffix write". 153 */ 154 public Object extra; 155 WritableTypeId()156 public WritableTypeId() { } 157 158 /** 159 * Constructor used when calling a method for generating and writing Type Id; 160 * caller only knows value object and its intended shape. 161 */ WritableTypeId(Object value, JsonToken valueShape0)162 public WritableTypeId(Object value, JsonToken valueShape0) { 163 this(value, valueShape0, null); 164 } 165 166 /** 167 * Constructor used when calling a method for generating and writing Type Id, 168 * but where actual type to use for generating id is NOT the type of value 169 * (but its supertype). 170 */ WritableTypeId(Object value, Class<?> valueType0, JsonToken valueShape0)171 public WritableTypeId(Object value, Class<?> valueType0, JsonToken valueShape0) { 172 this(value, valueShape0, null); 173 forValueType = valueType0; 174 } 175 176 /** 177 * Constructor used when calling a method for writing Type Id; 178 * caller knows value object, its intended shape as well as id to 179 * use; but not details of wrapping (if any). 180 */ WritableTypeId(Object value, JsonToken valueShape0, Object id0)181 public WritableTypeId(Object value, JsonToken valueShape0, Object id0) 182 { 183 forValue = value; 184 id = id0; 185 valueShape = valueShape0; 186 } 187 } 188