1 package com.fasterxml.jackson.databind.util; 2 3 import java.util.Collection; 4 import java.util.Collections; 5 import java.util.HashSet; 6 import java.util.Set; 7 8 /** 9 * @since 2.12 10 */ 11 public class IgnorePropertiesUtil 12 { 13 /** 14 * Decide if we need to ignore a property or not, given a set of field to ignore and a set of field to include. 15 */ shouldIgnore(Object value, Collection<String> toIgnore, Collection<String> toInclude)16 public static boolean shouldIgnore(Object value, Collection<String> toIgnore, Collection<String> toInclude) { 17 if (toIgnore == null && toInclude ==null) { 18 return false; 19 } 20 21 if (toInclude == null) { 22 return toIgnore.contains(value); 23 } 24 25 if (toIgnore == null) { 26 return !toInclude.contains(value); 27 } 28 29 // NOTE: conflict between both, JsonIncludeProperties will take priority. 30 return !toInclude.contains(value) || toIgnore.contains(value); 31 } 32 33 /** 34 * Factory method for creating and return a {@link Checker} instance if (and only if) 35 * one needed. 36 * 37 * @param toIgnore Set of property names to ignore (may be null) 38 * @param toInclude Set of only property names to include (if null, undefined) 39 * 40 * @return Checker, if validity checks are needed; {@code null} otherwise 41 */ buildCheckerIfNeeded(Set<String> toIgnore, Set<String> toInclude)42 public static Checker buildCheckerIfNeeded(Set<String> toIgnore, Set<String> toInclude) { 43 // First: no-op case 44 if ((toInclude == null) && ((toIgnore == null) || toIgnore.isEmpty())) { 45 return null; 46 } 47 return Checker.construct(toIgnore, toInclude); 48 } 49 50 /** 51 * Helper that encapsulates logic for combining two sets of "included names": 52 * default logic is to do intersection (name must be in both to be included 53 * in result) 54 * 55 * @param prevToInclude Existing set of names to include, if defined; null means "not defined" 56 * @param newToInclude New set of names to included, if defined; null means "not defined" 57 * 58 * @return Resulting set of names, using intersection if neither {@code null}; or the 59 * non-null one (if only one is {@code null}); or {@code null} if both arguments {@code null}. 60 */ combineNamesToInclude(Set<String> prevToInclude, Set<String> newToInclude)61 public static Set<String> combineNamesToInclude(Set<String> prevToInclude, 62 Set<String> newToInclude) { 63 if (prevToInclude == null) { 64 return newToInclude; 65 } 66 if (newToInclude == null) { 67 return prevToInclude; 68 } 69 final Set<String> result = new HashSet<>(); 70 71 // Make the intersection with the previously included properties 72 for (String prop : newToInclude) { 73 if (prevToInclude.contains(prop)) { 74 result.add(prop); 75 } 76 } 77 return result; 78 } 79 80 /** 81 * Helper class to encapsulate logic from static {@code shouldIgnore} method 82 * of util class. 83 */ 84 public final static class Checker 85 implements java.io.Serializable 86 { 87 private static final long serialVersionUID = 1L; 88 89 private final Set<String> _toIgnore; 90 private final Set<String> _toInclude; 91 Checker(Set<String> toIgnore, Set<String> toInclude)92 private Checker(Set<String> toIgnore, Set<String> toInclude) { 93 if (toIgnore == null) { 94 toIgnore = Collections.emptySet(); 95 } 96 _toIgnore = toIgnore; 97 _toInclude = toInclude; 98 } 99 construct(Set<String> toIgnore, Set<String> toInclude)100 public static Checker construct(Set<String> toIgnore, Set<String> toInclude) { 101 return new Checker(toIgnore, toInclude); 102 } 103 104 // May seem odd but during serialization key is not cast up to String: shouldIgnore(Object propertyName)105 public boolean shouldIgnore(Object propertyName) { 106 return ((_toInclude != null) && !_toInclude.contains(propertyName)) 107 || _toIgnore.contains(propertyName); 108 } 109 } 110 } 111