1 package org.example.customer.utility;
2
3 /*
4 * This is free and unencumbered software released into the public domain.
5 * Anyone is free to copy, modify, publish, use, compile, sell, or distribute this software,
6 * either in source code form or as a compiled binary, for any purpose, commercial or
7 * non-commercial, and by any means.
8 *
9 * In jurisdictions that recognize copyright laws, the author or authors of this
10 * software dedicate any and all copyright interest in the software to the public domain.
11 * We make this dedication for the benefit of the public at large and to the detriment of
12 * our heirs and successors. We intend this dedication to be an overt act of relinquishment in
13 * perpetuity of all present and future rights to this software under copyright law.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
16 * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
17 * PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES
18 * OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
20 *
21 * For more information, please refer to: https://unlicense.org/
22 */
23
24 import java.io.Serializable;
25
26 import org.apache.commons.lang3.builder.EqualsBuilder;
27 import org.apache.commons.lang3.builder.HashCodeBuilder;
28 import org.apache.logging.log4j.LogManager;
29 import org.apache.logging.log4j.Logger;
30 import org.example.websecurity.XssSanitizer;
31 import org.example.websecurity.XssSanitizerImpl;
32
33 /**
34 * The Customer Location for the Customer application.
35 <br>
36 <br>
37 * This class represents the common City and Country fields in the Customer Database
38 *
39 * @author Jonathan Earl
40 * @version 1.0
41 *
42 */
43 public class Location
44 implements Serializable
45 {
46 private static final long serialVersionUID = 1L;
47
48 private static final Logger LOG = LogManager.getLogger();
49
50 private String myCity;
51 private String myCountry;
52
53 private XssSanitizer mySanitizer;
54
55 /**
56 * The default constructor for the Location class.
57 * <p>
58 * The initial values are:
59 * <ul>
60 * <li>city: New York City</li>
61 * <li>country: United States of America</li>
62 * </ul>
63 */
64 public Location()
65 {
66 this(new XssSanitizerImpl());
67 LOG.debug("Finishing the default Constructor");
68 }
69
70 /**
71 * The overloaded constructor for the Location class that takes an XssSanitizer as input.
72 * <p>
73 * The initial values are:
74 * <ul>
75 * <li>city: New York City</li>
76 * <li>country: United States of America</li>
77 * </ul>
78 *
79 * @param sanitizer the XssSanitizer used by this instance
80 */
81 public Location(final XssSanitizer sanitizer)
82 {
83 LOG.debug("Starting the overloaded Constructor");
84 final String initialCity = "New York City";
85 final String initialCountry = "United States of America";
86
87 mySanitizer = sanitizer;
88
89 setCity(initialCity);
90 setCountry(initialCountry);
91 }
92
93
94 /**
95 * Returns the city value for the Location.
96 *
97 * @return the city value for the location
98 */
99 public String getCity()
100 {
101 LOG.debug("returning the City: " + myCity);
102 return myCity;
103 }
104
105 /**
106 * Sets the city value for the Location.
107 * <p>
108 * The business rules are:
109 * <ul>
110 * <li>the city <strong>may</strong> be null</li>
111 * <li>the city must <strong>not</strong> be empty</li>
112 * <li>the city must min length of 2 chars</li>
113 * <li>the city must max length of 40 chars</li>
114 * <li>XSS strings within the city will be removed</li>
115 * </ul>
116 *
117 * @param city the value to set into the location city field
118 * @throws IllegalArgumentException if the city is invalid
119 */
120 public void setCity(final String city)
121 {
122 LOG.debug("setting the City");
123 final int max = 40;
124 final int min = 2;
125
126 if (city == null)
127 {
128 LOG.debug("City is set to null");
129 this.myCity = null;
130 return;
131 }
132
133 String safeCity = mySanitizer.sanitizeInput(city);
134 if (safeCity.isEmpty())
135 {
136 LOG.error("City must not be empty");
137 throw new IllegalArgumentException("City must not be empty");
138 }
139 if (safeCity.length() > max || safeCity.length() < min)
140 {
141 LOG.error("City must be between 2 and 40 chars in length");
142 throw new IllegalArgumentException("City must be between 2 and 40 chars in length");
143 }
144 LOG.debug("setting the City to: " + safeCity);
145 this.myCity = safeCity;
146 }
147
148 /**
149 * Returns the country value for the Location.
150 *
151 * @return the country value for the location
152 */
153 public String getCountry()
154 {
155 LOG.debug("returning the Country: " + myCountry);
156 return myCountry;
157 }
158
159 /**
160 * Sets the country value for the Location.
161 * <p>
162 * The business rules are:
163 * <ul>
164 * <li>the country <strong>may</strong> be null</li>
165 * <li>the country must <strong>not</strong> be empty</li>
166 * <li>the country must min length of 2 chars</li>
167 * <li>the country must max length of 40 chars</li>
168 * <li>XSS strings within the country will be removed</li>
169 * </ul>
170 *
171 * @param country the value to set into the location country field
172 * @throws IllegalArgumentException if the country is invalid
173 */
174 public void setCountry(final String country)
175 {
176 LOG.debug("setting the Country");
177 final int max = 40;
178 final int min = 2;
179
180 if (country == null)
181 {
182 LOG.debug("Country is set to null");
183 this.myCountry = null;
184 return;
185 }
186
187 String safeCountry = mySanitizer.sanitizeInput(country);
188 if (safeCountry.isEmpty())
189 {
190 LOG.error("Country must not be empty");
191 throw new IllegalArgumentException("Country must not be empty");
192 }
193 if (safeCountry.length() > max || safeCountry.length() < min)
194 {
195 LOG.error("Country must be between 2 and 40 chars in length");
196 throw new IllegalArgumentException("Country must be between 2 and 40 chars in length");
197 }
198 LOG.debug("setting the Country to: " + safeCountry);
199 this.myCountry = safeCountry;
200 }
201
202 /**
203 * The hashCode() method of the Location class.
204 * <p>
205 * <strong>This method uses:</strong>
206 * <ul>
207 * <li>city</li>
208 * <li>country</li>
209 * </ul>
210 *
211 * @see java.lang.Object#hashCode()
212 * @return the hashCode value for this Location object
213 */
214 @Override
215 public int hashCode()
216 {
217 LOG.debug("building HashCode");
218 return new HashCodeBuilder()
219 .append(getCity())
220 .append(getCountry())
221 .toHashCode();
222 }
223
224 /**
225 * The equals() method of the Location class.
226 * <p>
227 * <strong>This method uses:</strong>
228 * <ul>
229 * <li>city</li>
230 * <li>country</li>
231 * </ul>
232 *
233 * @see java.lang.Object#equals(Object obj)
234 * @param obj the incoming object to compare against
235 * @return true if the fields being compared are equal
236 */
237 @Override
238 public boolean equals(final Object obj)
239 {
240 LOG.debug("checking equals");
241 if (obj instanceof Location)
242 {
243 final Location other = (Location) obj;
244 return new EqualsBuilder()
245 .append(getCity(), other.getCity())
246 .append(getCountry(), other.getCountry())
247 .isEquals();
248 }
249 else
250 {
251 return false;
252 }
253 }
254
255 /**
256 * The toString method for the Location class.
257 *
258 * this method will return:<br>
259 * Location [City=xxx Country=XXX]
260 */
261 @Override
262 public String toString()
263 {
264 return "Location [City=" + myCity + ", Country=" + myCountry + "]";
265 }
266
267 }