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