View Javadoc
1   /*
2    * Copyright (C) 2020-2023 Dipl.-Inform. Kai Hofmann. All rights reserved!
3    */
4   package de.powerstat.validation.values.impl;
5   
6   
7   import java.util.Map;
8   import java.util.Objects;
9   import java.util.concurrent.ConcurrentHashMap;
10  
11  import de.powerstat.validation.containers.NTuple2;
12  
13  
14  /**
15   * IBAN verifier.
16   */
17  public final class IBANVerifier
18   {
19    /**
20     * Cache for singletons.
21     */
22    private static final Map<NTuple2<Integer, String>, IBANVerifier> CACHE = new ConcurrentHashMap<>();
23  
24    /**
25     * IBAN length.
26     */
27    private final int length;
28  
29    /**
30     * IBAN regexp.
31     */
32    private final String regexp;
33  
34  
35    /**
36     * Constructor.
37     *
38     * @param length Country specific maximum IBAN length.
39     * @param regexp Country specific regular expression
40     */
41    private IBANVerifier(final int length, final String regexp)
42     {
43      super();
44      if ((length < 15) || (length > 34))
45       {
46        throw new IllegalArgumentException("Wrong length, must be between 15 and 34"); //$NON-NLS-1$
47       }
48      Objects.requireNonNull(regexp, "regexp"); //$NON-NLS-1$
49      // TODO test regexp length and allowed characters
50      if ((regexp.charAt(0) != '^') || (regexp.charAt(regexp.length() - 1) != '$'))
51       {
52        throw new IllegalArgumentException("Regexp does not start with ^ or ends with $"); //$NON-NLS-1$
53       }
54      this.length = length;
55      this.regexp = regexp;
56     }
57  
58  
59    /**
60     * IBAN verifier factory.
61     *
62     * @param length Country specific maximum IBAN length.
63     * @param regexp Country specific regular expression
64     * @return IBAN verifier object
65     */
66    public static IBANVerifier of(final int length, final String regexp)
67     {
68      final NTuple2<Integer, String> tuple = NTuple2.of(length, regexp);
69      synchronized (IBANVerifier.class)
70       {
71        IBANVerifier obj = IBANVerifier.CACHE.get(tuple);
72        if (obj != null)
73         {
74          return obj;
75         }
76        obj = new IBANVerifier(length, regexp);
77        IBANVerifier.CACHE.put(tuple, obj);
78        return obj;
79       }
80     }
81  
82  
83    /**
84     * Verify country specific iban.
85     *
86     * @param iban IBAN
87     * @return true when IBAN is ok, false otherwise
88     */
89    public boolean verify(final String iban)
90     {
91      Objects.requireNonNull(iban, "iban"); //$NON-NLS-1$
92      return ((iban.length() == this.length) && iban.matches(this.regexp));
93     }
94  
95   }