1+ package com .maxmind .minfraud .request ;
2+
3+ import com .fasterxml .jackson .annotation .JsonAnyGetter ;
4+ import com .maxmind .minfraud .AbstractModel ;
5+
6+ import java .util .Collections ;
7+ import java .util .HashMap ;
8+ import java .util .Map ;
9+ import java .util .regex .Pattern ;
10+
11+ /**
12+ * Custom inputs to be used in
13+ * <a href="https://www.maxmind.com/en/minfraud-interactive/#/custom-rules">Custom Rules</a>.
14+ * In order to use custom inputs, you must set them up from your account portal.
15+ */
16+ public final class CustomInputs extends AbstractModel {
17+ private final Map <String , Object > inputs ;
18+
19+ private CustomInputs (Builder builder ) {
20+ inputs = Collections .unmodifiableMap (new HashMap <>(builder .inputs ));
21+ }
22+
23+ /**
24+ * {@code Builder} creates instances of {@code CustomInputs}
25+ * from values set by the builder's methods.
26+ */
27+ public static class Builder {
28+ private static final long NUM_MAX = 1L << 53 ;
29+ private static final Pattern KEY_PATTERN = Pattern .compile ("^[a-z0-9_]{1,25}$" );
30+
31+ final Map <String , Object > inputs = new HashMap <>();
32+
33+ /**
34+ * Add a string custom input.
35+ *
36+ * @param key The key for the custom input as defined on your account
37+ * portal.
38+ * @param value The custom input value. Must be less than 256 characters
39+ * and must not contain new lines.
40+ * @return The builder object.
41+ * @throws IllegalArgumentException when the key or value are invalid.
42+ */
43+ public Builder put (String key , String value ) {
44+ validateKey (key );
45+ if (value .length () > 255 || value .contains ("\n " ))
46+ throw new IllegalArgumentException ("The custom input string " +
47+ value + " is invalid. The string be less than" +
48+ "256 characters and the string must not contain a newline." );
49+ inputs .put (key , value );
50+ return this ;
51+ }
52+
53+ /**
54+ * Add a numeric custom input.
55+ *
56+ * @param key The key for the custom input as defined on your account
57+ * portal.
58+ * @param value The custom input value. Must be between -2^53 and 2^53,
59+ * exclusive.
60+ * @return The builder object.
61+ * @throws IllegalArgumentException when the key or value are invalid.
62+ */
63+ public Builder put (String key , Number value ) {
64+ validateKey (key );
65+ double doubleValue = value .doubleValue ();
66+ if (doubleValue <= -NUM_MAX || doubleValue >= NUM_MAX )
67+ throw new IllegalArgumentException (
68+ "The custom input number " + value + "is invalid. " +
69+ "The number must be between -" + NUM_MAX +
70+ " and " + NUM_MAX + ", exclusive." );
71+ inputs .put (key , value );
72+ return this ;
73+ }
74+
75+ /**
76+ * Add a boolean custom input.
77+ *
78+ * @param key The key for the custom input as defined on your account
79+ * portal.
80+ * @param value The custom input value.
81+ * @return The builder object.
82+ * @throws IllegalArgumentException when the key or value are invalid.
83+ */
84+ public Builder put (String key , boolean value ) {
85+ validateKey (key );
86+ inputs .put (key , value );
87+ return this ;
88+ }
89+
90+ /**
91+ * @return An instance of {@code CustomInputs} created from the
92+ * fields set on this builder.
93+ */
94+ public CustomInputs build () {
95+ return new CustomInputs (this );
96+ }
97+
98+
99+ private void validateKey (String key ) {
100+ if (!KEY_PATTERN .matcher (key ).matches ()) {
101+ throw new IllegalArgumentException ("The custom input key "
102+ + key + " is invalid." );
103+ }
104+ }
105+ }
106+
107+ /**
108+ * @return an unmodifiable map containing the custom inputs.
109+ */
110+ @ JsonAnyGetter
111+ public Map <String , Object > getInputs () {
112+ return inputs ;
113+ }
114+ }
0 commit comments