1 package org.example.customer;
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.customer.utility.CustomerEntity;
31 import org.example.customer.utility.Location;
32 import org.example.customer.utility.Phone;
33 import org.example.websecurity.XssSanitizer;
34 import org.example.websecurity.XssSanitizerImpl;
35
36 /**
37 * The Supplier Entity for the Customer application.
38 * <p>
39 * This class represents the following DB Table:
40 *
41 * <pre>
42 * CREATE TABLE SUPPLIER (
43 * ID INTEGER NOT NULL GENERATED ALWAYS AS IDENTITY (START WITH 1, INCREMENT BY 1),
44 * COMPANY_NAME VARCHAR(40) NOT NULL,
45 * CONTACT_NAME VARCHAR(50),
46 * CITY VARCHAR(40),
47 * COUNTRY VARCHAR(40),
48 * PHONE VARCHAR(20),
49 * FAX VARCHAR(30),
50 * CONSTRAINT PK_SUPPLIER PRIMARY KEY (ID)
51 * );
52 * </pre>
53 *
54 * @author Jonathan Earl
55 * @version 1.0
56 *
57 */
58 public class Supplier extends CustomerEntity
59 implements Serializable, Comparable<Supplier>
60 {
61 private static final long serialVersionUID = 1L;
62
63 private static final Logger LOG = LogManager.getLogger();
64
65 private String myCompanyName;
66 private String myContactName;
67 private Location myLocation;
68 private Phone myPhone;
69 private Phone myFax;
70
71 private XssSanitizer mySanitizer;
72
73 /**
74 * The default constructor for the Supplier class.
75 * <p>
76 * The initial values are:
77 * <ul>
78 * <li>id: 1</li>
79 * <li>first name: ABC Inc.</li>
80 * <li>last name: John Smith</li>
81 * <li>city: New York City</li>
82 * <li>country: United States of America</li>
83 * <li>phone: null</li>
84 * <li>fax: null</li>
85 * </ul>
86 */
87 public Supplier()
88 {
89 this(new XssSanitizerImpl());
90 LOG.debug("Finishing the default Constructor");
91 }
92
93 /**
94 * The overloaded constructor for the Supplier class that takes an XssSanitizer as input.
95 * <p>
96 * The initial values are:
97 * <ul>
98 * <li>id: 1</li>
99 * <li>first name: ABC Inc.</li>
100 * <li>last name: John Smith</li>
101 * <li>city: New York City</li>
102 * <li>country: United States of America</li>
103 * <li>phone: null</li>
104 * <li>fax: null</li>
105 * </ul>
106 *
107 * @param sanitizer the XssSanitizer used by this instance
108 */
109 public Supplier(final XssSanitizer sanitizer)
110 {
111 LOG.debug("Starting the overloaded Constructor");
112 final int initialId = 1;
113 final String initialCompanyName = "ABC Inc.";
114 final String initialContactName = "John Smith";
115 final String initialCity = "New York City";
116 final String initialCountry = "United States of America";
117 final String initialPhoneNumber = null;
118 final String initialFaxNumber = null;
119
120 mySanitizer = sanitizer;
121
122 setId(initialId);
123 setCompanyName(initialCompanyName);
124 setContactName(initialContactName);
125 Location temp = new Location();
126 temp.setCity(initialCity);
127 temp.setCountry(initialCountry);
128 setLocation(temp);
129 Phone temp2 = new Phone();
130 temp2.setNumber(initialPhoneNumber);
131 setPhone(temp2);
132 Phone temp3 = new Phone();
133 temp3.setNumber(initialFaxNumber);
134 setFax(temp2);
135 }
136
137 /**
138 * Returns the company name value for the Supplier.
139 *
140 * @return the company name value for the Supplier
141 */
142 public String getCompanyName()
143 {
144 LOG.debug("returning the Company Name: " + myCompanyName);
145 return myCompanyName;
146 }
147
148 /**
149 * This will enable sorting of Suppliers by company name.
150 * <br>
151 * <br>
152 * @param other the Supplier object to compare with
153 * @return the sort value of negative/zero/positive
154 */
155 @Override
156 public int compareTo(Supplier other)
157 {
158 return this.getCompanyName().compareToIgnoreCase(other.getCompanyName());
159 }
160
161 /**
162 * Sets the company name value for the Supplier.
163 * <p>
164 * The business rules are:
165 * <ul>
166 * <li>the company name must <strong>not</strong> be null</li>
167 * <li>the company name must <strong>not</strong> be empty</li>
168 * <li>the company name must max length of 40 chars</li>
169 * <li>XSS strings within the company name will be removed</li>
170 * </ul>
171 *
172 * @param companyName the value to set into the customer company name field
173 * @throws IllegalArgumentException if the company name is invalid
174 */
175 public void setCompanyName(final String companyName)
176 {
177 LOG.debug("setting the Company Name");
178 final int max = 40;
179
180 if (companyName == null)
181 {
182 LOG.error("Company Name must not be null");
183 throw new IllegalArgumentException("Company Name must not be null");
184 }
185
186 String safeCompanyName = mySanitizer.sanitizeInput(companyName);
187 if (safeCompanyName.isEmpty())
188 {
189 LOG.error("Company Name must not be empty");
190 throw new IllegalArgumentException("Company Name must not be empty");
191 }
192 if (safeCompanyName.length() > max)
193 {
194 LOG.error("Company Name must be up to 40 chars in length");
195 throw new IllegalArgumentException("Company Name must be up to 40 chars in length");
196 }
197 LOG.debug("setting the First Name to: " + safeCompanyName);
198 this.myCompanyName = safeCompanyName;
199 }
200
201 /**
202 * Returns the contactName value for the Supplier.
203 *
204 * @return the contactName value for the Supplier
205 */
206 public String getContactName()
207 {
208 LOG.debug("returning the contactName: " + myContactName);
209 return myContactName;
210 }
211
212 /**
213 * Sets the contactName value for the Supplier.
214 * <p>
215 * The business rules are:
216 * <ul>
217 * <li>the contactName <strong>may</strong> be null</li>
218 * <li>the contactName must <strong>not</strong> be empty</li>
219 * <li>the contactName must min length of 2 chars</li>
220 * <li>the contactName must max length of 50 chars</li>
221 * <li>XSS strings within the contactName will be removed</li>
222 * </ul>
223 *
224 * @param contactName the value to set into the customer city field
225 * @throws IllegalArgumentException if the city is invalid
226 */
227 public void setContactName(final String contactName)
228 {
229 LOG.debug("setting the ContactName");
230 final int max = 50;
231 final int min = 2;
232
233 if (contactName == null)
234 {
235 LOG.debug("ContactName is set to null");
236 this.myContactName = null;
237 return;
238 }
239
240 String safeContactName = mySanitizer.sanitizeInput(contactName);
241 if (safeContactName.isEmpty())
242 {
243 LOG.error("ContactName must not be empty");
244 throw new IllegalArgumentException("ContactName must not be empty");
245 }
246 if (safeContactName.length() > max || safeContactName.length() < min)
247 {
248 LOG.error("ContactName must be between 2 and 40 chars in length");
249 throw new IllegalArgumentException("ContactName must be between 2 and 40 chars in length");
250 }
251 LOG.debug("setting the ContactName to: " + safeContactName);
252 this.myContactName = safeContactName;
253 }
254
255 /**
256 * Return the Location for the Supplier.
257 * <br>
258 * <br>
259 * @return the myLocation
260 */
261 public Location getLocation()
262 {
263 LOG.debug("returning the Location: " + myLocation);
264 return myLocation;
265 }
266
267 /**
268 * Sets the location value for the Supplier.
269 * <p>
270 * The business rules are:
271 * <ul>
272 * <li>the location <strong>may</strong> be null</li>
273 * </ul>
274 *
275 * @param location the value to set into the supplier location field
276 * @throws IllegalArgumentException if the location is invalid
277 */
278 public void setLocation(final Location location)
279 {
280 LOG.debug("setting the Location");
281 if (location == null)
282 {
283 LOG.error("Location must not be null");
284 throw new IllegalArgumentException("Location must not be null");
285 }
286 this.myLocation = location;
287 }
288
289 /**
290 * Returns the phone value for the Supplier.
291 *
292 * @return the phone value for the supplier
293 */
294 public Phone getPhone()
295 {
296 LOG.debug("returning the Phone: " + myPhone);
297 return myPhone;
298 }
299
300 /**
301 * Sets the phone value for the Supplier.
302 * <p>
303 * The business rules are:
304 * <ul>
305 * <li>the phone <strong>may</strong> be null</li>
306 * </ul>
307 *
308 * @param phone the value to set into the supplier phone field
309 * @throws IllegalArgumentException if the phone is invalid
310 */
311 public void setPhone(final Phone phone)
312 {
313 LOG.debug("setting the Phone");
314 this.myPhone = phone;
315 }
316
317 /**
318 * Returns the fax value for the Supplier.
319 *
320 * @return the fax value for the supplier
321 */
322 public Phone getFax()
323 {
324 LOG.debug("returning the Fax: " + myPhone);
325 return myFax;
326 }
327
328 /**
329 * Sets the fax value for the Supplier.
330 * <p>
331 * The business rules are:
332 * <ul>
333 * <li>the fax <strong>may</strong> be null</li>
334 * </ul>
335 *
336 * @param fax the value to set into the supplier fax field
337 * @throws IllegalArgumentException if the phone is invalid
338 */
339 public void setFax(final Phone fax)
340 {
341 LOG.debug("setting the Fax");
342 this.myFax = fax;
343 }
344
345 /**
346 * The hashCode() method of the Supplier class.
347 * <p>
348 * <strong>This method uses:</strong>
349 * <ul>
350 * <li>id</li>
351 * <li>company name</li>
352 * <li>city</li>
353 * <li>country</li>
354 * <li>phone</li>
355 * </ul>
356 *
357 * @see java.lang.Object#hashCode()
358 * @return the hashCode value for this Customer object
359 */
360 @Override
361 public int hashCode()
362 {
363 LOG.debug("building HashCode");
364 return new HashCodeBuilder()
365 .append(getId())
366 .append(myCompanyName)
367 .append(myLocation.getCity())
368 .append(myLocation.getCountry())
369 .append(myPhone)
370 .toHashCode();
371 }
372
373 /**
374 * The equals() method of the Supplier class.
375 * <p>
376 * <strong>This method uses:</strong>
377 * <ul>
378 * <li>id</li>
379 * <li>company name</li>
380 * <li>city</li>
381 * <li>country</li>
382 * <li>phone</li>
383 * </ul>
384 *
385 * @see java.lang.Object#equals(Object obj)
386 * @param obj the incoming object to compare against
387 * @return true if the fields being compared are equal
388 */
389 @Override
390 public boolean equals(final Object obj)
391 {
392 LOG.debug("checking equals");
393 if (obj instanceof Supplier)
394 {
395 final Supplier other = (Supplier) obj;
396 return new EqualsBuilder()
397 .append(getId(), other.getId())
398 .append(myCompanyName, other.myCompanyName)
399 .append(myLocation.getCity(), other.myLocation.getCity())
400 .append(myLocation.getCountry(), other.myLocation.getCountry())
401 .append(myPhone, other.myPhone)
402 .isEquals();
403 }
404 else
405 {
406 return false;
407 }
408 }
409
410 /**
411 * The toString method for the Supplier class.
412 *
413 * this method will return:<br>
414 * Supplier [Id=xxx, CompanyName=xxx, City=xxx,
415 * myCountry=xxx, myPhone=xxx]
416 */
417 @Override
418 public String toString()
419 {
420 return "Supplier [Id=" + getId() + ", CompanyName=" + myCompanyName + ", City=" + myLocation.getCity()
421 + ", Country=" + myLocation.getCountry() + ", Phone=" + myPhone.getNumber() + "]";
422 }
423 }
424