3131 * if disabled (`OptBoolean.FALSE`), input value (if any) will be ignored;
3232 * otherwise it will override injected value.
3333 *<p>
34- * Default is `OptBoolean.DEFAULT`, which translates to `OptBoolean.TRUE`: this is
35- * for backwards compatibility (2.8 and earlier always allow binding input value).
34+ * Default is `OptBoolean.DEFAULT`, which translates to `OptBoolean.TRUE`.
3635 *
3736 * @return {@link OptBoolean#TRUE} to enable use of value from input instead of
3837 * injected value, if available; {@link OptBoolean#FALSE} if injected value will
3938 * always be used regardless of input.
40- *
41- * @since 2.9
4239 */
4340 public OptBoolean useInput () default OptBoolean .DEFAULT ;
4441
42+ /**
43+ * Whether to throw an exception when the {@code ObjectMapper} does not find
44+ * the value to inject.
45+ *<p>
46+ * Default is {@code OptBoolean.DEFAULT} for backwards-compatibility: in this
47+ * case {@code ObjectMapper} defaults are used (which in turn are same
48+ * as {code OptBoolean.FALSE}).
49+ *
50+ * @return {@link OptBoolean#FALSE} to throw an exception; {@link OptBoolean#TRUE}
51+ * to avoid throwing it; or {@link OptBoolean#DEFAULT} to use configure defaults
52+ * (which are same as {@link OptBoolean#FALSE} for Jackson 2.x)
53+ */
54+ public OptBoolean optional () default OptBoolean .DEFAULT ;
55+
4556 /*
46- /**********************************************************
47- /* Value class used to enclose information, allow for
48- /* merging of layered configuration settings, and eventually
49- /* decouple higher level handling from Annotation types
50- /* (which can not be implemented etc.)
51- /**********************************************************
57+ /**********************************************************************
58+ /* Value class used to enclose information, allow for merging of layered
59+ /* configuration settings, and eventually decouple higher level handling
60+ /* from Annotation types (which can not be implemented etc.)
61+ /**********************************************************************
5262 */
5363
5464 /**
5565 * Helper class used to contain information from a single {@link JacksonInject}
5666 * annotation, as well as to provide possible overrides from non-annotation sources.
57- *
58- * @since 2.9
5967 */
6068 public static class Value
6169 implements JacksonAnnotationValue <JacksonInject >,
6270 java .io .Serializable
6371 {
6472 private static final long serialVersionUID = 1L ;
6573
66- protected final static Value EMPTY = new Value (null , null );
74+ protected final static Value EMPTY = new Value (null , null , null );
6775
6876 /**
6977 * Id to use to access injected value; if `null`, "default" name, derived
@@ -73,9 +81,12 @@ public static class Value
7381
7482 protected final Boolean _useInput ;
7583
76- protected Value (Object id , Boolean useInput ) {
84+ protected final Boolean _optional ;
85+
86+ protected Value (Object id , Boolean useInput , Boolean optional ) {
7787 _id = id ;
7888 _useInput = useInput ;
89+ _optional = optional ;
7990 }
8091
8192 @ Override
@@ -84,40 +95,40 @@ public Class<JacksonInject> valueFor() {
8495 }
8596
8697 /*
87- /**********************************************************
98+ /******************************************************************
8899 /* Factory methods
89- /**********************************************************
100+ /******************************************************************
90101 */
91102
92103 public static Value empty () {
93104 return EMPTY ;
94105 }
95106
96- public static Value construct (Object id , Boolean useInput ) {
107+ public static Value construct (Object id , Boolean useInput , Boolean optional ) {
97108 if ("" .equals (id )) {
98109 id = null ;
99110 }
100- if (_empty (id , useInput )) {
111+ if (_empty (id , useInput , optional )) {
101112 return EMPTY ;
102113 }
103- return new Value (id , useInput );
114+ return new Value (id , useInput , optional );
104115 }
105116
106117 public static Value from (JacksonInject src ) {
107118 if (src == null ) {
108119 return EMPTY ;
109120 }
110- return construct (src .value (), src .useInput ().asBoolean ());
121+ return construct (src .value (), src .useInput ().asBoolean (), src . optional (). asBoolean () );
111122 }
112123
113124 public static Value forId (Object id ) {
114- return construct (id , null );
125+ return construct (id , null , null );
115126 }
116127
117128 /*
118- /**********************************************************
129+ /******************************************************************
119130 /* Mutant factory methods
120- /**********************************************************
131+ /******************************************************************
121132 */
122133
123134 public Value withId (Object id ) {
@@ -128,7 +139,7 @@ public Value withId(Object id) {
128139 } else if (id .equals (_id )) {
129140 return this ;
130141 }
131- return new Value (id , _useInput );
142+ return new Value (id , _useInput , _optional );
132143 }
133144
134145 public Value withUseInput (Boolean useInput ) {
@@ -139,17 +150,29 @@ public Value withUseInput(Boolean useInput) {
139150 } else if (useInput .equals (_useInput )) {
140151 return this ;
141152 }
142- return new Value (_id , useInput );
153+ return new Value (_id , useInput , _optional );
154+ }
155+
156+ public Value withOptional (Boolean optional ) {
157+ if (optional == null ) {
158+ if (_optional == null ) {
159+ return this ;
160+ }
161+ } else if (optional .equals (_optional )) {
162+ return this ;
163+ }
164+ return new Value (_id , _useInput , optional );
143165 }
144166
145167 /*
146- /**********************************************************
168+ /******************************************************************
147169 /* Accessors
148- /**********************************************************
170+ /******************************************************************
149171 */
150172
151173 public Object getId () { return _id ; }
152174 public Boolean getUseInput () { return _useInput ; }
175+ public Boolean getOptional () { return _optional ; }
153176
154177 public boolean hasId () {
155178 return _id != null ;
@@ -160,15 +183,15 @@ public boolean willUseInput(boolean defaultSetting) {
160183 }
161184
162185 /*
163- /**********************************************************
164- /* Std method overrides
165- /**********************************************************
186+ /******************************************************************
187+ /* Standard method overrides
188+ /******************************************************************
166189 */
167190
168191 @ Override
169192 public String toString () {
170- return String .format ("JacksonInject.Value(id=%s,useInput=%s)" ,
171- _id , _useInput );
193+ return String .format ("JacksonInject.Value(id=%s,useInput=%s,optional=%s )" ,
194+ _id , _useInput , _optional );
172195 }
173196
174197 @ Override
@@ -180,6 +203,9 @@ public int hashCode() {
180203 if (_useInput != null ) {
181204 h += _useInput .hashCode ();
182205 }
206+ if (_optional != null ) {
207+ h += _optional .hashCode ();
208+ }
183209 return h ;
184210 }
185211
@@ -189,24 +215,25 @@ public boolean equals(Object o) {
189215 if (o == null ) return false ;
190216 if (o .getClass () == getClass ()) {
191217 Value other = (Value ) o ;
192- if (OptBoolean .equals (_useInput , other ._useInput )) {
193- if (_id == null ) {
194- return other ._id == null ;
195- }
196- return _id .equals (other ._id );
197- }
218+
219+ return (_id == null && other ._id == null
220+ || _id != null && _id .equals (other ._id ))
221+ && (_useInput == null && other ._useInput == null
222+ || _useInput != null && _useInput .equals (other ._useInput ))
223+ && (_optional == null && other ._optional == null
224+ || _optional != null && _optional .equals (other ._optional ));
198225 }
199226 return false ;
200227 }
201228
202229 /*
203- /**********************************************************
230+ /******************************************************************
204231 /* Other
205- /**********************************************************
232+ /******************************************************************
206233 */
207234
208- private static boolean _empty (Object id , Boolean useInput ) {
209- return (id == null ) && (useInput == null );
235+ private static boolean _empty (Object id , Boolean useInput , Boolean optional ) {
236+ return (id == null ) && (useInput == null ) && optional == null ;
210237 }
211238 }
212239}
0 commit comments