1 package com.fasterxml.jackson.annotation; 2 3 import java.lang.annotation.ElementType; 4 import java.lang.annotation.Retention; 5 import java.lang.annotation.RetentionPolicy; 6 import java.lang.annotation.Target; 7 8 /** 9 * Annotation used to indicate when value of the annotated property (when 10 * used for a field, method or constructor parameter), or all 11 * properties of the annotated class, is to be serialized. 12 * Without annotation property values are always included, but by using 13 * this annotation one can specify simple exclusion rules to reduce 14 * amount of properties to write out. 15 *<p> 16 * Note that the main inclusion criteria (one annotated with {@link #value}) 17 * is checked on <b>Java object level</b>, for the annotated type, 18 * and <b>NOT</b> on JSON output -- so even with {@link Include#NON_NULL} 19 * it is possible that JSON null values are output, if object reference 20 * in question is not `null`. An example is {@link java.util.concurrent.atomic.AtomicReference} 21 * instance constructed to reference <code>null</code> value: such a value 22 * would be serialized as JSON null, and not filtered out. 23 *<p> 24 * To base inclusion on value of contained value(s), you will typically also need 25 * to specify {@link #content()} annotation; for example, specifying only 26 * {@link #value} as {@link Include#NON_EMPTY} for a {link java.util.Map} would 27 * exclude <code>Map</code>s with no values, but would include <code>Map</code>s 28 * with `null` values. To exclude Map with only `null` value, you would use both 29 * annotations like so: 30 *<pre> 31 *public class Bean { 32 * {@literal @JsonInclude}(value=Include.NON_EMPTY, content=Include.NON_NULL) 33 * public Map<String,String> entries; 34 *} 35 *</pre> 36 * Similarly you could Maps that only contain 37 * "empty" elements, or "non-default" values (see {@link Include#NON_EMPTY} and 38 * {@link Include#NON_DEFAULT} for more details). 39 *<p> 40 * In addition to `Map`s, `content` concept is also supported for referential 41 * types (like {@link java.util.concurrent.atomic.AtomicReference}). 42 * Note that `content` is NOT currently (as of Jackson 2.9) supported for 43 * arrays or {@link java.util.Collection}s, but supported may be added in 44 * future versions. 45 * 46 * @since 2.0 47 */ 48 @Target({ElementType.ANNOTATION_TYPE, ElementType.METHOD, ElementType.FIELD, 49 ElementType.TYPE, ElementType.PARAMETER}) 50 @Retention(RetentionPolicy.RUNTIME) 51 @JacksonAnnotation 52 public @interface JsonInclude 53 { 54 /** 55 * Inclusion rule to use for instances (values) of types (Classes) or 56 * properties annotated; defaults to {@link Include#ALWAYS}. 57 */ value()58 public Include value() default Include.ALWAYS; 59 60 /** 61 * Inclusion rule to use for entries ("content") of annotated 62 * {@link java.util.Map}s and referential types (like 63 * {@link java.util.concurrent.atomic.AtomicReference}); 64 * defaults to {@link Include#ALWAYS}. 65 * 66 * @since 2.5 67 */ content()68 public Include content() default Include.ALWAYS; 69 70 /** 71 * Specifies type of "Filter Object" to use in case 72 * {@link #value} is {@link JsonInclude.Include#CUSTOM}: 73 * if so, an instance is created by calling <code>HandlerInstantiator</code> 74 * (of <code>ObjectMapper</code>), which by default simply calls 75 * zero-argument constructor of the Filter Class. 76 * 77 * @since 2.9 78 */ valueFilter()79 public Class<?> valueFilter() default Void.class; 80 81 /** 82 * Specifies type of "Filter Object" to use in case 83 * {@link #content} is {@link JsonInclude.Include#CUSTOM}: 84 * if so, an instance is created by calling <code>HandlerInstantiator</code> 85 * (of <code>ObjectMapper</code>), which by default simply calls 86 * zero-argument constructor of the Filter Class. 87 * 88 * @since 2.9 89 */ contentFilter()90 public Class<?> contentFilter() default Void.class; 91 92 /* 93 /********************************************************** 94 /* Value enumerations 95 /********************************************************** 96 */ 97 98 /** 99 * Enumeration used with {@link JsonInclude} 100 * to define which properties 101 * of Java Beans are to be included in serialization. 102 */ 103 public enum Include 104 { 105 /** 106 * Value that indicates that property is to be always included, 107 * independent of value of the property. 108 */ 109 ALWAYS, 110 111 /** 112 * Value that indicates that only properties with non-null 113 * values are to be included. 114 */ 115 NON_NULL, 116 117 /** 118 * Value that indicates that properties are included unless their value 119 * is: 120 *<ul> 121 * <li>null</li> 122 * <li>"absent" value of a referential type (like Java 8 `Optional`, or 123 * {link java.util.concurrent.atomic.AtomicReference}); that is, something 124 * that would not deference to a non-null value. 125 * </ul> 126 * This option is mostly used to work with "Optional"s (Java 8, Guava). 127 * 128 * @since 2.6 129 */ 130 NON_ABSENT, 131 132 /** 133 * Value that indicates that only properties with null value, 134 * or what is considered empty, are not to be included. 135 * Definition of emptiness is data type specific; see below 136 * for details on actual handling. 137 *<p> 138 * Default emptiness for all types includes: 139 *<ul> 140 * <li><code>Null</code> values.</li> 141 * <li>"Absent" values (see {@link #NON_ABSENT})</li> 142 *</ul> 143 * so that as baseline, "empty" set includes values that would be 144 * excluded by both {@link #NON_NULL} and {@link #NON_ABSENT}. 145 *<br> 146 * Beyond this base, following types have additional empty values: 147 *<ul> 148 * <li>For {@link java.util.Collection}s and {@link java.util.Map}s, 149 * method <code>isEmpty()</code> is called; 150 * </li> 151 * <li>For Java arrays, empty arrays are ones with length of 0 152 * </li> 153 * <li>For Java {@link java.lang.String}s, <code>length()</code> is called, 154 * and return value of 0 indicates empty String 155 * </li> 156 * </ul> 157 * and for other types, null values are excluded but other exclusions (if any). 158 *<p> 159 * Note that this default handling can be overridden by custom 160 * <code>JsonSerializer</code> implementation: if method <code>isEmpty()</code> 161 * is overridden, it will be called to see if non-null values are 162 * considered empty (null is always considered empty). 163 *<p> 164 * Compatibility note: Jackson 2.6 included a wider range of "empty" values than 165 * either earlier (up to 2.5) or later (2.7 and beyond) types; specifically: 166 *<ul> 167 * <li>Default values of primitive types (like <code>0</code> for `int`/`java.lang.Integer` 168 * and `false` for `bool`/`Boolean`) 169 * </li> 170 * <li>Timestamp 0 for date/time types 171 * </li> 172 *</ul> 173 * With 2.7, definition has been tightened back to only containing types explained 174 * above (null, absent, empty String, empty containers), and now 175 * extended definition may be specified using {@link #NON_DEFAULT}. 176 */ 177 NON_EMPTY, 178 179 /** 180 * Meaning of this setting depends on context: whether annotation is 181 * specified for POJO type (class), or not. In latter case annotation 182 * is either used as the global default, or as property override. 183 *<p> 184 * When used for a POJO, definition is that only values that differ from 185 * the default values of POJO properties are included. This is done 186 * by creating an instance of POJO using zero-argument constructor, 187 * and accessing property values: value is used as the default value 188 * by using <code>equals()</code> method, except for the case where property 189 * has `null` value in which case straight null check is used. 190 *<p> 191 * When NOT used for a POJO (that is, as a global default, or as property 192 * override), definition is such that: 193 *<ul> 194 * <li>All values considered "empty" (as per {@link #NON_EMPTY}) are excluded</li> 195 * <li>Primitive/wrapper default values are excluded</li> 196 * <li>Date/time values that have timestamp (`long` value of milliseconds since 197 * epoch, see {@link java.util.Date}) of `0L` are excluded</li> 198 * </ul> 199 */ 200 NON_DEFAULT, 201 202 /** 203 * Value that indicates that separate `filter` Object (specified by 204 * {@link JsonInclude#valueFilter} for value itself, and/or 205 * {@link JsonInclude#contentFilter} for contents of structured types) 206 * is to be used for determining inclusion criteria. 207 * Filter object's <code>equals()</code> method is called with value 208 * to serialize; if it returns <code>true</code> value is <b>excluded</b> 209 * (that is, filtered out); if <code>false</code> value is <b>included</b>. 210 * 211 * @since 2.9 212 */ 213 CUSTOM, 214 215 /** 216 * Pseudo-value used to indicate that the higher-level defaults make 217 * sense, to avoid overriding inclusion value. For example, if returned 218 * for a property this would use defaults for the class that contains 219 * property, if any defined; and if none defined for that, then 220 * global serialization inclusion details. 221 * 222 * @since 2.6 223 */ 224 USE_DEFAULTS 225 226 ; 227 } 228 229 /* 230 /********************************************************** 231 /* Value class used to enclose information 232 /********************************************************** 233 */ 234 235 /** 236 * Helper class used to contain information from a single {@link JsonInclude} 237 * annotation. 238 * 239 * @since 2.6 240 */ 241 public static class Value 242 implements JacksonAnnotationValue<JsonInclude>, // since 2.6 243 java.io.Serializable 244 { 245 private static final long serialVersionUID = 1L; 246 247 protected final static Value EMPTY = new Value(Include.USE_DEFAULTS, 248 Include.USE_DEFAULTS, null, null); 249 250 protected final Include _valueInclusion; 251 protected final Include _contentInclusion; 252 253 /** 254 * @since 2.9 255 */ 256 protected final Class<?> _valueFilter; 257 258 /** 259 * @since 2.9 260 */ 261 protected final Class<?> _contentFilter; 262 Value(JsonInclude src)263 public Value(JsonInclude src) { 264 this(src.value(), src.content(), 265 src.valueFilter(), src.contentFilter()); 266 } 267 Value(Include vi, Include ci, Class<?> valueFilter, Class<?> contentFilter)268 protected Value(Include vi, Include ci, 269 Class<?> valueFilter, Class<?> contentFilter) { 270 _valueInclusion = (vi == null) ? Include.USE_DEFAULTS : vi; 271 _contentInclusion = (ci == null) ? Include.USE_DEFAULTS : ci; 272 _valueFilter = (valueFilter == Void.class) ? null : valueFilter; 273 _contentFilter = (contentFilter == Void.class) ? null : contentFilter; 274 } 275 empty()276 public static Value empty() { 277 return EMPTY; 278 } 279 280 /** 281 * Helper method that will try to combine values from two {@link Value} 282 * instances, using one as base settings, and the other as overrides 283 * to use instead of base values when defined; base values are only 284 * use if override does not specify a value (matching value is null 285 * or logically missing). 286 * Note that one or both of value instances may be `null`, directly; 287 * if both are `null`, result will also be `null`; otherwise never null. 288 * 289 * @since 2.8 290 */ merge(Value base, Value overrides)291 public static Value merge(Value base, Value overrides) 292 { 293 return (base == null) ? overrides 294 : base.withOverrides(overrides); 295 } 296 297 /** 298 * @since 2.8 299 */ mergeAll(Value... values)300 public static Value mergeAll(Value... values) 301 { 302 Value result = null; 303 for (Value curr : values) { 304 if (curr != null) { 305 result = (result == null) ? curr : result.withOverrides(curr); 306 } 307 } 308 return result; 309 } 310 311 // for JDK serialization readResolve()312 protected Object readResolve() { 313 if ((_valueInclusion == Include.USE_DEFAULTS) 314 && (_contentInclusion == Include.USE_DEFAULTS) 315 && (_valueFilter == null) 316 && (_contentFilter == null) 317 ) { 318 return EMPTY; 319 } 320 return this; 321 } 322 323 /** 324 * Mutant factory method that merges values of this value with given override 325 * values, so that any explicitly defined inclusion in overrides has precedence over 326 * settings of this value instance. If no overrides exist will return <code>this</code> 327 * instance; otherwise new {@link Value} with changed inclusion values. 328 */ withOverrides(Value overrides)329 public Value withOverrides(Value overrides) { 330 if ((overrides == null) || (overrides == EMPTY)) { 331 return this; 332 } 333 Include vi = overrides._valueInclusion; 334 Include ci = overrides._contentInclusion; 335 Class<?> vf = overrides._valueFilter; 336 Class<?> cf = overrides._contentFilter; 337 338 boolean viDiff = (vi != _valueInclusion) && (vi != Include.USE_DEFAULTS); 339 boolean ciDiff = (ci != _contentInclusion) && (ci != Include.USE_DEFAULTS); 340 boolean filterDiff = (vf != _valueFilter) || (cf != _valueFilter); 341 342 if (viDiff) { 343 if (ciDiff) { 344 return new Value(vi, ci, vf, cf); 345 } 346 return new Value(vi, _contentInclusion, vf, cf); 347 } else if (ciDiff) { 348 return new Value(_valueInclusion, ci, vf, cf); 349 } else if (filterDiff) { 350 return new Value(_valueInclusion, _contentInclusion, vf, cf); 351 } 352 return this; 353 } 354 355 /** 356 * Factory method to use for constructing an instance for components 357 */ construct(Include valueIncl, Include contentIncl)358 public static Value construct(Include valueIncl, Include contentIncl) { 359 if (((valueIncl == Include.USE_DEFAULTS) || (valueIncl == null)) 360 && ((contentIncl == Include.USE_DEFAULTS) || (contentIncl == null))) { 361 return EMPTY; 362 } 363 return new Value(valueIncl, contentIncl, null, null); 364 } 365 366 /** 367 * Factory method to use for constructing an instance for components 368 * 369 * @since 2.9 370 */ construct(Include valueIncl, Include contentIncl, Class<?> valueFilter, Class<?> contentFilter)371 public static Value construct(Include valueIncl, Include contentIncl, 372 Class<?> valueFilter, Class<?> contentFilter) 373 { 374 if (valueFilter == Void.class) { 375 valueFilter = null; 376 } 377 if (contentFilter == Void.class) { 378 contentFilter = null; 379 } 380 if (((valueIncl == Include.USE_DEFAULTS) || (valueIncl == null)) 381 && ((contentIncl == Include.USE_DEFAULTS) || (contentIncl == null)) 382 && (valueFilter == null) 383 && (contentFilter == null) 384 ) { 385 return EMPTY; 386 } 387 return new Value(valueIncl, contentIncl, valueFilter, contentFilter); 388 } 389 390 /** 391 * Factory method to use for constructing an instance from instance of 392 * {@link JsonInclude} 393 */ from(JsonInclude src)394 public static Value from(JsonInclude src) { 395 if (src == null) { 396 return EMPTY; 397 } 398 Include vi = src.value(); 399 Include ci = src.content(); 400 401 if ((vi == Include.USE_DEFAULTS) && (ci == Include.USE_DEFAULTS)) { 402 return EMPTY; 403 } 404 Class<?> vf = src.valueFilter(); 405 if (vf == Void.class) { 406 vf = null; 407 } 408 Class<?> cf = src.contentFilter(); 409 if (cf == Void.class) { 410 cf = null; 411 } 412 return new Value(vi, ci, vf, cf); 413 } 414 withValueInclusion(Include incl)415 public Value withValueInclusion(Include incl) { 416 return (incl == _valueInclusion) ? this 417 : new Value(incl, _contentInclusion, _valueFilter, _contentFilter); 418 } 419 420 /** 421 * Mutant factory that will either 422 *<ul> 423 * <li>Set <code>value</code> as <code>USE_DEFAULTS</code> 424 * and <code>valueFilter</code> to <code>filter</code> (if filter not null); 425 * or</li> 426 * <li>Set <code>value</code> as <code>ALWAYS</code> (if filter null) 427 * </li> 428 * </ul> 429 * 430 * @since 2.9 431 */ withValueFilter(Class<?> filter)432 public Value withValueFilter(Class<?> filter) { 433 Include incl; 434 if (filter == null || filter == Void.class) { // clear filter 435 incl = Include.USE_DEFAULTS; 436 filter = null; 437 } else { 438 incl = Include.CUSTOM; 439 } 440 return construct(incl, _contentInclusion, filter, _contentFilter); 441 } 442 443 /** 444 * Mutant factory that will either 445 *<ul> 446 * <li>Set <code>content</code> as <code>USE_DEFAULTS</code> 447 * and <code>contentFilter</code> to <code>filter</code> (if filter not null); 448 * or</li> 449 * <li>Set <code>content</code> as <code>ALWAYS</code> (if filter null) 450 * </li> 451 * </ul> 452 * 453 * @since 2.9 454 */ withContentFilter(Class<?> filter)455 public Value withContentFilter(Class<?> filter) { 456 Include incl; 457 if (filter == null || filter == Void.class) { // clear filter 458 incl = Include.USE_DEFAULTS; 459 filter = null; 460 } else { 461 incl = Include.CUSTOM; 462 } 463 return construct(_valueInclusion, incl, _valueFilter, filter); 464 } 465 withContentInclusion(Include incl)466 public Value withContentInclusion(Include incl) { 467 return (incl == _contentInclusion) ? this 468 : new Value(_valueInclusion, incl, _valueFilter, _contentFilter); 469 } 470 471 @Override valueFor()472 public Class<JsonInclude> valueFor() { 473 return JsonInclude.class; 474 } 475 getValueInclusion()476 public Include getValueInclusion() { 477 return _valueInclusion; 478 } 479 getContentInclusion()480 public Include getContentInclusion() { 481 return _contentInclusion; 482 } 483 getValueFilter()484 public Class<?> getValueFilter() { 485 return _valueFilter; 486 } 487 getContentFilter()488 public Class<?> getContentFilter() { 489 return _contentFilter; 490 } 491 492 @Override toString()493 public String toString() { 494 StringBuilder sb = new StringBuilder(80); 495 sb.append("JsonInclude.Value(value=") 496 .append(_valueInclusion) 497 .append(",content=") 498 .append(_contentInclusion); 499 if (_valueFilter != null) { 500 sb.append(",valueFilter=").append(_valueFilter.getName()).append(".class"); 501 } 502 if (_contentFilter != null) { 503 sb.append(",contentFilter=").append(_contentFilter.getName()).append(".class"); 504 } 505 return sb.append(')').toString(); 506 } 507 508 @Override hashCode()509 public int hashCode() { 510 return (_valueInclusion.hashCode() << 2) 511 + _contentInclusion.hashCode(); 512 } 513 514 @Override equals(Object o)515 public boolean equals(Object o) { 516 if (o == this) return true; 517 if (o == null) return false; 518 if (o.getClass() != getClass()) return false; 519 Value other = (Value) o; 520 521 return (other._valueInclusion == _valueInclusion) 522 && (other._contentInclusion == _contentInclusion) 523 && (other._valueFilter == _valueFilter) 524 && (other._contentFilter == _contentFilter) 525 ; 526 } 527 } 528 } 529