View Javadoc
1   package uk.pallas.systems.typr.rest.entities.v1.validation;
2   
3   import io.swagger.v3.oas.annotations.media.ArraySchema;
4   import io.swagger.v3.oas.annotations.media.Schema;
5   import java.util.Collection;
6   import java.util.HashSet;
7   import java.util.Objects;
8   import uk.pallas.systems.typr.entities.v1.validation.EnumValidationRule;
9   
10  /**
11   * Some field definitions have a limited number of allowed string values and so this definition allows us to maintain
12   * a list rather than a regular expression.
13   */
14  @Schema(description = "Some field definitions have a limited number of allowed string values and so this definition "
15    + "allows us to maintain a list rather than a regular expression. ")
16  public class EnumValidationRuleDTO extends AbstractValidationRuleDTO implements EnumValidationRule {
17  
18    /** List of values which are allowed within the field. */
19    @ArraySchema(schema = @Schema(description = "List of enumerates, which are allowed.",
20      implementation = String.class, example = "UK"))
21    private final Collection<String> enumerates;
22  
23  
24    /**
25     * Default constructor, sets everything to null and makes validation optional.
26     */
27    public EnumValidationRuleDTO() {
28      this(null, null);
29    }
30  
31    /**
32     * Constructor, allows us to set the internal abstract fields.
33     *
34     * @param detailedDescription the description of the rule
35     * @param data                Enumerate values we need to support.
36     */
37    public EnumValidationRuleDTO(final String detailedDescription, final Collection<String> data) {
38      super(detailedDescription);
39  
40      this.enumerates = new HashSet<>();
41      if (null != data) {
42        this.enumerates.addAll(data);
43      }
44    }
45  
46    /**
47     * Copy Constructor, passes up to parent Copy Constructor.
48     *
49     * @param data the object to create a duplicate off.
50     */
51    public EnumValidationRuleDTO(final EnumValidationRule data) {
52      this(null == data ? null : data.getDescription(), null == data ? null : data.getEnumerates());
53    }
54  
55    /**
56     * Compares the supplied object to this one, it checks the supplied object is a FieldDefinition and then checks
57     * the definition applies validation, its name and description to see if they are matching objects.
58     *
59     * @param toCompare the object to compare (can be null or a child class, etc..)
60     * @return false if the name/validation and description fields in a field definition are
61     *               different (or it isn't a field definition).
62     */
63    @Override
64    public boolean equals(final Object toCompare) {
65  
66      final boolean result;
67      if (this == toCompare) {
68        result = true;
69      } else if (toCompare instanceof EnumValidationRule that) {
70        result = super.equals(toCompare)
71          && this.getEnumerates().containsAll(that.getEnumerates())
72          && that.getEnumerates().containsAll(this.getEnumerates());
73      } else {
74        result = false;
75      }
76  
77      return result;
78    }
79  
80    /**
81     * Generates a Unique hashcode for the field definition class.
82     *
83     * @return a valid integer representation of this object,
84     */
85    @Override
86    public int hashCode() {
87      return Objects.hash(super.hashCode(), this.getEnumerates());
88    }
89  
90  
91    @Override
92    public Collection<String> getEnumerates() {
93      return new HashSet<>(this.enumerates);
94    }
95  
96    @Override
97    public void setEnumerates(final Collection<String> enums) {
98      if (null == enums) {
99        this.enumerates.clear();
100     } else {
101       this.enumerates.clear();
102       this.enumerates.addAll(enums);
103     }
104   }
105 
106   /**
107    * Is the supplied test object something that matches against our field definition regular expression?
108    * <p>
109    * If validation optional is set to true this will return true, if the supplied object is null, this will always
110    * return false. Otherwise this will call toString and then match the field definition regex tp confirm the object
111    * matches our desired value.
112    *
113    * @param toTest to test is valid
114    * @return false if the object fails the validation match.
115    */
116   @Override
117   public boolean isValid(final Object toTest) {
118     final boolean result;
119 
120     if (toTest instanceof String) {
121       // Use to string as it leaves things the most flexible in our regex comparison.
122       result = this.isValid((String) toTest);
123     } else {
124       result = false;
125     }
126 
127     return result;
128   }
129 
130   /**
131    * Is the supplied test object something that matches against our field definition regular expression?
132    * <p>
133    * If validation optional is set to true this will return true, if the supplied object is null, this will always
134    * return false. Otherwise it will call matches on the supplied string.
135    *
136    * @param toTest to test is valid
137    * @return false if the object fails the validation match.
138    */
139   public boolean isValid(final String toTest) {
140     final boolean result;
141 
142     if (null == toTest) {
143       result = false;
144     } else {
145       result = this.getEnumerates().contains(toTest);
146     }
147 
148     return result;
149   }
150 }