Project Report: fawkez

Packagesummary org.jcoderz.commons.types

org.jcoderz.commons.types.EmailAddress

LineHitsNoteSource
1  /*
2   * $Id: EmailAddress.java 1404 2009-04-14 12:34:34Z amandel $
3   *
4   * Copyright 2006, The jCoderZ.org Project. All rights reserved.
5   *
6   * Redistribution and use in source and binary forms, with or without
7   * modification, are permitted provided that the following conditions are
8   * met:
9   *
10   *    * Redistributions of source code must retain the above copyright
11   *      notice, this list of conditions and the following disclaimer.
12   *    * Redistributions in binary form must reproduce the above
13   *      copyright notice, this list of conditions and the following
14   *      disclaimer in the documentation and/or other materials
15   *      provided with the distribution.
16   *    * Neither the name of the jCoderZ.org Project nor the names of
17   *      its contributors may be used to endorse or promote products
18   *      derived from this software without specific prior written
19   *      permission.
20   *
21   * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS" AND
22   * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23   * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
24   * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS AND CONTRIBUTORS
25   * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
26   * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
27   * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
28   * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
29   * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
30   * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
31   * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32   */
33  package org.jcoderz.commons.types;
34  
35  import java.io.Serializable;
36  import java.util.regex.Matcher;
37  import java.util.regex.Pattern;
38  
39  import org.jcoderz.commons.ArgumentMalformedException;
40  import org.jcoderz.commons.util.Assert;
41  import org.jcoderz.commons.util.HashCodeUtil;
42  import org.jcoderz.commons.util.StringUtil;
43  
44  /**
45   * This class represents an email addresses compliant to RFC 2822,
46   * chapter 3.4.1. Addr-spec specification.
47   * This class does not support obsolete addressing (see ch. 4.4.
48   * Obsolete Addressing).
49   *
50   * <pre>
51   * atext           =       ALPHA / DIGIT / ; Any character except controls,
52   *                         "!" / "#" /     ;  SP, and specials.
53   *                         "$" / "%" /     ;  Used for atoms
54   *                         "&" / "'" /
55   *                         "*" / "+" /
56   *                         "-" / "/" /
57   *                         "=" / "?" /
58   *                         "^" / "_" /
59   *                         "`" / "{" /
60   *                         "|" / "}" /
61   *                         "~"
62   * atom            =       [CFWS] 1*atext [CFWS]
63   * dot-atom        =       [CFWS] dot-atom-text [CFWS]
64   * dot-atom-text   =       1*atext *("." 1*atext)
65   * addr-spec       = local-part "@" domain
66   * local-part      = dot-atom / quoted-string
67   * qtext           =       NO-WS-CTL /     ; Non white space controls
68   *                         %d33 /          ; The rest of the US-ASCII
69   *                         %d35-91 /       ;  characters not including "\"
70   *                         %d93-126        ;  or the quote character
71   * qcontent        =       qtext / quoted-pair
72   * quoted-string   = [CFWS]
73   *                   DQUOTE *([FWS] qcontent) [FWS] DQUOTE
74   *                   [CFWS]
75   * domain          = dot-atom / domain-literal
76   * domain-literal  = [CFWS] "[" *([FWS] dcontent) [FWS] "]" [CFWS]
77   * dcontent        = dtext / quoted-pair
78   * dtext           = NO-WS-CTL /     ; Non white space controls
79   *                   %d33-90 /       ; The rest of the US-ASCII
80   *                   %d94-126        ;  characters not including "[",
81   *                                   ;  "]", or "\"
82   * FWS             =       ([*WSP CRLF] 1*WSP) /   ; Folding white space
83   *                         obs-FWS
84   * ctext           =       NO-WS-CTL /     ; Non white space controls
85   *                         %d33-39 /       ; The rest of the US-ASCII
86   *                         %d42-91 /       ;  characters not including "(",
87   *                         %d93-126        ;  ")", or "\"
88   * ccontent        =       ctext / quoted-pair / comment
89   * comment         =       "(" *([FWS] ccontent) [FWS] ")"
90   * CFWS            =       *([FWS] comment) (([FWS] comment) / FWS)
91   * </pre>
92   *
93   * <p>The maximum length of an email address is:
94   * 64+1+255 characters (local-part + @ + domain).
95   * The minimum length of an email address is: 
96   * 1+1+4 characters (local-part + @ + domain).</p>
97   *
98   * <p>A valid list of top-level domains is defined by the IANA. A top-level
99   * domain which is not part of the
100   * <a href="http://data.iana.org/TLD/tlds-alpha-by-domain.txt">official list</a>
101   * will be rejected.</p>
102   *
103   * @author Michael Rumpf
104   */
105  public class EmailAddress
106    implements Serializable
107  {
108    private static final long serialVersionUID = 1L;
109  
110    private static final int MAX_LENGTH_LOCAL_PART = 64;
111    private static final int MAX_LENGTH_DOMAIN = 255;
112  
113    // RFC 2822 token definitions for a valid email
114    private static final String SP = "!#$%&'*+-/=?^_`{|}~";
115    private static final String ATEXT = "[a-zA-Z0-9" + SP + "]";
116    private static final String ATOM = ATEXT + "+";
117  
118    // one or more atext chars
119    private static final String DOT_ATOM = "\\." + ATOM;
120    // one atom followed by 0 or more dotAtoms.
121    private static final String LOCAL_PART = ATOM + "(" + DOT_ATOM + ")*";
122  
123    // RFC 1035 tokens for domain names:
124    private static final String LETTER = "[a-zA-Z]";
125    private static final String LET_DIG = "[a-zA-Z0-9]";
126    private static final String LET_DIG_HYP = "[a-zA-Z0-9-]";
127    private static final String RFC_LABEL
128        = LET_DIG + LET_DIG_HYP + "{0,61}" + LET_DIG;
129    private static final String DOMAIN
130        = RFC_LABEL + "(\\." + RFC_LABEL + ")*\\." + LETTER + "{2,6}";
131  
132    //Combined together, these form the allowed email regexp allowed by RFC 2822:
133    private static final String ADDRESS = "^" + LOCAL_PART + "@" + DOMAIN + "$";
134  
135100   private static final Pattern ADDRESS_PATTERN = Pattern.compile(ADDRESS);
136  
137  
138    private final String mLocalPart;
139    private final String mDomain;
140    private final String mTopLevelDomain;
141  
142    /**
143     * This is the constructor of the EmailAddress type.
144     *
145     * @param email The email address.
146     */
147    public EmailAddress (String email)
148100   {
149100(1)    Assert.notNull(email, "email");
150100     final String mail = email.trim();
151100     final Matcher matcher = ADDRESS_PATTERN.matcher(email);
152100     if (!matcher.matches())
153      {
154100(2)      throw new ArgumentMalformedException("email", email,
155            "EMail pattern does not match the RFC2822 grammar!");
156      }
157  
158100     final int at = mail.indexOf('@');
159100     if (at > MAX_LENGTH_LOCAL_PART)
160      {
1610(3)      throw new ArgumentMalformedException("email", email,
162            "The local part is longer than " + MAX_LENGTH_LOCAL_PART
163            + " characters!");
164      }
165100     if (mail.length() - at - 1 > MAX_LENGTH_DOMAIN)
166      {
1670(4)      throw new ArgumentMalformedException("email", email,
168            "The domain is longer than " + MAX_LENGTH_DOMAIN
169            + " characters!");
170      }
171100     mLocalPart = mail.substring(0, at);
172100     mDomain = mail.substring(at + 1);
173  
174100     final int dot = mail.lastIndexOf('.');
175100     mTopLevelDomain = mail.substring(dot + 1);
176100   }
177  
178    /**
179     * Factory method for converting a String into an instance of type 
180     * EmailAddress.
181     *
182     * @param email the email address to parse
183     * @return An instance of type EmailAddress
184     */
185 (5)  public static EmailAddress fromString(String email)
186    {
1870     return new EmailAddress(email);
188    }
189  
190    /**
191     * Returns the local part of the address.
192     * @return the local part of the address.
193     */
194    public String getName ()
195    {
196100     return mLocalPart;
197    }
198  
199  
200    /**
201     * Returns the domain name of the address.
202     * @return the domain name of the address.
203     */
204    public String getDomain ()
205    {
206100     return mDomain;
207    }
208  
209  
210    /**
211     * Returns the top-level domain name of the address.
212     * @return the top-level domain name of the address.
213     */
214    public String getTopLevelDomain ()
215    {
2160     return mTopLevelDomain;
217    }
218  
219  
220    /**
221     * Returns the full email address.
222     * @return the full email address.
223     */
224    public String getAddress ()
225    {
2260     return mLocalPart + "@" + mDomain;
227    }
228  
229    /**
230     * Returns the full email address.
231     * @return the full email address.
232     */
233    public String toString ()
234    {
2350     return mLocalPart + "@" + mDomain;
236    }
237  
238    /**
239     * Returns the true if this email address equals the other.
240     * @param obj the object to compare to.
241     * @return the true if this email address equals the other.
242     * @see java.lang.Object#equals(java.lang.Object)
243     */
244    public boolean equals (Object obj)
245    {
2460     boolean result = false;
2470     if (this == obj)
248      {
2490       result = true;
250      }
2510     else if (obj instanceof EmailAddress)
252      {
2530       final EmailAddress other = (EmailAddress) obj;
2540       if (StringUtil.equals(getDomain(), other.getDomain())
255            && StringUtil.equals(getName(), other.getName()))
256        {
2570         result = true;
258        }
259      }
2600     return result;
261    }
262  
263    /**
264     * Returns the hash code for this email.
265     * @return the hash code for this email.
266     */
267    public int hashCode ()
268    {
2690(6)    int hashCode = HashCodeUtil.hash(HashCodeUtil.SEED, mLocalPart);
2700     return HashCodeUtil.hash(hashCode, mDomain);
271    }
272  }

Findings in this File

i (1) 149 : 27 The String literal "email" appears 4 times in this file; the first occurrence is on line 149
i (2) 154 : 0 method new org.jcoderz.commons.types.EmailAddress(String) throws exception with static message string
i (3) 161 : 0 method new org.jcoderz.commons.types.EmailAddress(String) throws exception with static message string
i (4) 167 : 0 method new org.jcoderz.commons.types.EmailAddress(String) throws exception with static message string
c (5) 185 : 40 '(' is not preceded with whitespace.
c (6) 269 : 9 Variable 'hashCode' should be declared final.