View Javadoc
1   /*
2    * Copyright (C) 2020-2023 Dipl.-Inform. Kai Hofmann. All rights reserved!
3    */
4   package de.powerstat.validation.values;
5   
6   
7   import java.util.Objects;
8   import java.util.regex.Pattern;
9   
10  import de.powerstat.validation.interfaces.IValueObject;
11  
12  
13  /**
14   * Address Postal code.
15   *
16   * Not DSGVO relevant.
17   *
18   * https://en.wikipedia.org/wiki/List_of_postal_codes
19   * https://de.wikipedia.org/wiki/Liste_der_Postleitsysteme
20   *
21   * TODO Country specific
22   */
23  public final class PostalCode implements Comparable<PostalCode>, IValueObject
24   {
25    /* *
26     * Cache for singletons.
27     */
28    // private static final Map<String, PostalCode> CACHE = new WeakHashMap<>();
29  
30    /**
31     * Postal code regexp.
32     */
33    private static final Pattern POSTALCODE_REGEXP = Pattern.compile("^[0-9A-Z -]{3,11}$"); //$NON-NLS-1$
34  
35    /**
36     * Postal code.
37     */
38    private final String postalCode;
39  
40  
41    /**
42     * Constructor.
43     *
44     * @param postalCode Postal code
45     * @throws NullPointerException if postalCode is null
46     * @throws IllegalArgumentException if postalCode is not a correct postalCode
47     */
48    private PostalCode(final String postalCode)
49     {
50      super();
51      Objects.requireNonNull(postalCode, "postalCode"); //$NON-NLS-1$
52      if ((postalCode.length() < 3) || (postalCode.length() > 11))
53       {
54        throw new IllegalArgumentException("postalCode with wrong length"); //$NON-NLS-1$
55       }
56      if (!PostalCode.POSTALCODE_REGEXP.matcher(postalCode).matches())
57       {
58        throw new IllegalArgumentException("postalCode with wrong format"); //$NON-NLS-1$
59       }
60      this.postalCode = postalCode;
61     }
62  
63  
64    /**
65     * PostalCode factory.
66     *
67     * @param postalCode Postal code
68     * @return PostalCode object
69     */
70    public static PostalCode of(final String postalCode)
71     {
72      /*
73      synchronized (PostalCode.class)
74       {
75        PostalCode obj = PostalCode.CACHE.get(postalCode);
76        if (obj != null)
77         {
78          return obj;
79         }
80        obj = new PostalCode(postalCode);
81        PostalCode.CACHE.put(postalCode, obj);
82        return obj;
83       }
84      */
85      return new PostalCode(postalCode);
86     }
87  
88  
89    /**
90     * Returns the value of this PostalCode as a string.
91     *
92     * @return The text value represented by this object after conversion to type string.
93     */
94    @Override
95    public String stringValue()
96     {
97      return this.postalCode;
98     }
99  
100 
101   /**
102    * Calculate hash code.
103    *
104    * @return Hash
105    * @see java.lang.Object#hashCode()
106    */
107   @Override
108   public int hashCode()
109    {
110     return this.postalCode.hashCode();
111    }
112 
113 
114   /**
115    * Is equal with another object.
116    *
117    * @param obj Object
118    * @return true when equal, false otherwise
119    * @see java.lang.Object#equals(java.lang.Object)
120    */
121   @Override
122   public boolean equals(final Object obj)
123    {
124     if (this == obj)
125      {
126       return true;
127      }
128     if (!(obj instanceof PostalCode))
129      {
130       return false;
131      }
132     final PostalCode other = (PostalCode)obj;
133     return this.postalCode.equals(other.postalCode);
134    }
135 
136 
137   /**
138    * Returns the string representation of this PostalCode.
139    *
140    * The exact details of this representation are unspecified and subject to change, but the following may be regarded as typical:
141    *
142    * "PostalCode[postalCode=28000]"
143    *
144    * @return String representation of this PostalCode
145    * @see java.lang.Object#toString()
146    */
147   @Override
148   public String toString()
149    {
150     final var builder = new StringBuilder(23);
151     builder.append("PostalCode[postalCode=").append(this.postalCode).append(']'); //$NON-NLS-1$
152     return builder.toString();
153    }
154 
155 
156   /**
157    * Compare with another object.
158    *
159    * @param obj Object to compare with
160    * @return 0: equal; 1: greater; -1: smaller
161    * @see java.lang.Comparable#compareTo(java.lang.Object)
162    */
163   @Override
164   public int compareTo(final PostalCode obj)
165    {
166     Objects.requireNonNull(obj, "obj"); //$NON-NLS-1$
167     return this.postalCode.compareTo(obj.postalCode);
168    }
169 
170  }