2020
2121import java .util .ArrayList ;
2222import java .util .List ;
23+ import java .util .Objects ;
2324import java .util .concurrent .ConcurrentHashMap ;
2425
2526import org .apache .commons .lang3 .StringUtils ;
3435 */
3536public final class ClaimValidator {
3637 /**
37- * The map of max counter limits.
38+ * The map of max counter limits.
3839 */
3940 private final ConcurrentHashMap <ClaimStatistic .Counter , MutableInt > max = new ConcurrentHashMap <>();
4041 /**
41- * The map of min counter limits.
42+ * The map of min counter limits.
4243 */
4344 private final ConcurrentHashMap <ClaimStatistic .Counter , MutableInt > min = new ConcurrentHashMap <>();
4445 /**
@@ -48,13 +49,24 @@ public final class ClaimValidator {
4849
4950 /**
5051 * Constructor.
52+ * Visible for testing.
53+ * @param withData if {@code true} the max and min are loaded with data from the Counter definitions.
5154 */
52- public ClaimValidator () {
53- for (ClaimStatistic .Counter counter : ClaimStatistic .Counter .values ()) {
54- max .put (counter ,
55- new MutableInt (counter .getDefaultMaxValue () < 0 ? Integer .MAX_VALUE : counter .getDefaultMaxValue ()));
56- min .put (counter , new MutableInt (counter .getDefaultMinValue ()));
55+ ClaimValidator (final boolean withData ) {
56+ if (withData ) {
57+ for (ClaimStatistic .Counter counter : ClaimStatistic .Counter .values ()) {
58+ max .put (counter ,
59+ new MutableInt (counter .getDefaultMaxValue () < 0 ? Integer .MAX_VALUE : counter .getDefaultMaxValue ()));
60+ min .put (counter , new MutableInt (counter .getDefaultMinValue ()));
61+ }
5762 }
63+
64+ }
65+ /**
66+ * Constructor.
67+ */
68+ public ClaimValidator () {
69+ this (true );
5870 }
5971
6072 /**
@@ -65,71 +77,127 @@ public boolean hasErrors() {
6577 return hasErrors ;
6678 }
6779
80+ /**
81+ * Sets the value unconditionally.
82+ * @param result the MutableInt to set.
83+ * @param value the value to set it to.
84+ * @return the {@code result} argument
85+ */
86+ private MutableInt newValue (final MutableInt result , final int value ) {
87+ result .setValue (value );
88+ return result ;
89+ }
90+
91+ /**
92+ * Sets the {@code result.value} if it is greater than the {@code value} argument.
93+ * @param result the MutableInt to set.
94+ * @param value the value to set it to if it is less than the {@code result.value}.
95+ * @return the {@code result} argument
96+ */
97+ private MutableInt setMinValue (final MutableInt result , final int value ) {
98+ if (result .intValue () > value ) {
99+ result .setValue (value );
100+ }
101+ return result ;
102+ }
103+
104+ /**
105+ * Sets the {@code result.value} if it is less than the {@code value} argument.
106+ * @param result the MutableInt to set.
107+ * @param value the value to set it to if it is greater than the {@code result.value}.
108+ * @return the {@code result} argument
109+ */
110+ private MutableInt setMaxValue (final MutableInt result , final int value ) {
111+ if (result .intValue () < value ) {
112+ result .setValue (value );
113+ }
114+ return result ;
115+ }
116+
68117 /**
69118 * Sets the max value for the specified counter.
119+ * Will adjust the minimum if the minimum is greater than the maximum.
70120 * @param counter the counter to set the limit for.
71121 * @param value the value to set. A negative value specifies no maximum value.
72122 */
73123 public void setMax (final ClaimStatistic .Counter counter , final int value ) {
74- MutableInt maxValue = max .compute (counter , (k , v ) -> {
75- v .setValue (value < 0 ? Integer .MAX_VALUE : value );
76- return v ; });
77- min .compute (counter , (k , v ) -> {
78- if (v .intValue () > maxValue .intValue ()) {
79- v .setValue (maxValue .intValue ());
80- }
81- return v ; });
124+ if (counter == null ) {
125+ DefaultLog .getInstance ().warn ("`null` passed as argument to setMax() -- ignoring" );
126+ return ;
127+ }
128+ int setValue = value < 0 ? Integer .MAX_VALUE : value ;
129+ MutableInt maxValue = max .compute (counter , (k , v ) ->
130+ v == null ? new MutableInt (setValue ) : newValue (v , setValue ));
131+ min .compute (counter , (k , v ) ->
132+ v == null ? new MutableInt (Math .min (k .getDefaultMinValue (), maxValue .intValue ())) :
133+ setMinValue (v , setValue ));
82134 }
83135
84136 /**
85137 * Sets the min value for the specified counter.
138+ * Will adjust the maximum if the maximum is less than the minimum.
86139 * @param counter the counter to set the limit for.
87140 * @param value the value to set. A negative value specifies no maximum value.
88141 */
89142 public void setMin (final ClaimStatistic .Counter counter , final int value ) {
90- min .put (counter , new MutableInt (value ));
91- max .compute (counter , (k , v ) -> {
92- if (v .intValue () < value ) {
93- v .setValue (value );
94- }
95- return v ; });
143+ if (counter == null ) {
144+ DefaultLog .getInstance ().warn ("`null` passed as argument to setMin() -- ignoring" );
145+ return ;
146+ }
147+ min .compute (counter , (k , v ) ->
148+ v == null ? new MutableInt (value ) : newValue (v , value ));
149+ max .compute (counter , (k , v ) ->
150+ v == null ? setMaxValue (new MutableInt (k .getDefaultMaxValue ()), value ) :
151+ setMaxValue (v , value ));
96152 }
97153
98154 /**
99- * Gets the limit for the specific counter.
155+ * Gets the max limit for the specific counter.
100156 * @param counter the counter to get the limit for.
101157 * @return the limit for the counter or 0 if not set.
102158 */
103159 public int getMax (final ClaimStatistic .Counter counter ) {
160+ if (counter == null ) {
161+ DefaultLog .getInstance ().warn ("`null` passed as argument to getMax() -- returning 0" );
162+ return 0 ;
163+ }
104164 return max .get (counter ).intValue ();
105165 }
106166
107167 /**
108- * Gets the limit for the specific counter.
168+ * Gets the min limit for the specific counter.
109169 * @param counter the counter to get the limit for.
110- * @return the limit for the counter or 0 if not set.
170+ * @return the limit for the counter or zero if not set.
111171 */
112172 public int getMin (final ClaimStatistic .Counter counter ) {
173+ if (counter == null ) {
174+ DefaultLog .getInstance ().warn ("`null` passed as argument to getMin() -- returning 0" );
175+ return 0 ;
176+ }
113177 return min .get (counter ).intValue ();
114178 }
115179
116180 /**
117181 * Determines if the specified count is within the limits for the counter.
118- * @param counter The counter to check.
182+ * @param counter the counter to check.
119183 * @param count the limit to check.
120184 * @return {@code true} if the count is within the limits, {@code false} otherwise.
185+ * @throws NullPointerException if counter is {@code null}.
121186 */
122187 public boolean isValid (final ClaimStatistic .Counter counter , final int count ) {
188+ Objects .requireNonNull (counter , "counter must not be null." );
123189 boolean result = max .get (counter ).intValue () >= count && min .get (counter ).intValue () <= count ;
124190 hasErrors |= !result ;
125191 return result ;
126192 }
127193
128194 /**
129195 * Logs all the invalid values as errors.
130- * @param statistic The statistics that contain the run values.
196+ * @param statistic the statistics that contain the run's values.
197+ * @throws NullPointerException if statistic is {@code null}.
131198 */
132199 public void logIssues (final ClaimStatistic statistic ) {
200+ Objects .requireNonNull (statistic , "statistic must not be null." );
133201 for (ClaimStatistic .Counter counter : ClaimStatistic .Counter .values ()) {
134202 if (!isValid (counter , statistic .getCounter (counter ))) {
135203 DefaultLog .getInstance ().error (format ("Unexpected count for %s, limit is [%s,%s]. Count: %s" , counter ,
@@ -142,10 +210,12 @@ public void logIssues(final ClaimStatistic statistic) {
142210
143211 /**
144212 * Creates a list of items that have issues.
145- * @param statistic The statistics that contain the run values.
213+ * @param statistic the statistics that contain the run values.
146214 * @return a collection of counter names that are invalid.
215+ * @throws NullPointerException if statistic is {@code null}.
147216 */
148217 public List <String > listIssues (final ClaimStatistic statistic ) {
218+ Objects .requireNonNull (statistic , "statistic must not be null." );
149219 List <String > result = new ArrayList <>();
150220 for (ClaimStatistic .Counter counter : ClaimStatistic .Counter .values ()) {
151221 if (!isValid (counter , statistic .getCounter (counter ))) {
0 commit comments