Subversion Repositories javautils

Rev

Go to most recent revision | Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
3 daniel-mar 1
package de.viathinksoft.utils.mail;
2
 
3
import java.net.IDN;
4
 
5
import de.viathinksoft.utils.mail.syntaxchecker.MailSyntaxChecker;
6
 
7
/**
8
 *
9
 * This class parses an email address (trims whitespaces from it) and stores it
10
 * in its original form as well as store a RFC-compatible punycoded domainpart.
11
 * So, if you enter a Unicode-Mail-Address you can easily access the trimmed and
12
 * punycoded domain-part mail-address. Warning! This class does NOT check if the
13
 * email address is fully valid. Please use the syntax checker class for this.
14
 *
15
 * @author Daniel Marschall
16
 *
17
 */
18
public class EMailAddress {
19
 
20
        // Constants
21
 
22
        /**
23
         * This constant is used by toString() and tells if whether
24
         * getMailAddressUnicode() or getMailAddressPunycodedDomain() should be
25
         * returned.
26
         */
27
        static boolean USE_UNICODE_AS_STANDARD = false;
28
 
29
        // Attributes
30
 
31
        /**
32
         * The local part of our parsed mail address. (Part before "@") It is
33
         * allways Unicode, since the mail servers have to take care about it. Even
34
         * if Unicode mail addresses will become popular in future, the local part
35
         * will probably not punycoded.
36
         */
37
        private String localPart;
38
        /**
39
         * The domain part of our parsed mail address (part after "@") inclusive our
40
         * top level domain (TLD). It is in its Unicode form.
41
         */
42
        private String domainPartUnicode;
43
 
44
        /**
45
         * The domain part of our parsed mail address (part after "@") inclusive our
46
         * top level domain (TLD). It is in its Punycode (ASCII) form.
47
         */
48
        private String domainPartPunycode;
49
 
50
        /**
51
         * The top level domain (COM, ORG, BIZ...) of our parsed mail address. The
52
         * dot is not included. It is in its Unicode form.
53
         */
54
        private String tldUnicode;
55
 
56
        /**
57
         * The top level domain (COM, ORG, BIZ...) of our parsed mail address. The
58
         * dot is not included. It is in its Punycode form.
59
         */
60
        private String tldPunycode;
61
 
62
        // Getter and Setter
63
 
64
        /**
65
         * The local part of our parsed mail address. (Part before "@") It is
66
         * allways Unicode, since the mail servers have to take care about it. Even
67
         * if Unicode mail addresses will become popular in future, the local part
68
         * will probably not punycoded.
69
         *
70
         * @return The local part
71
         */
72
        public String getLocalPart() {
73
                return localPart;
74
        }
75
 
76
        /**
77
         * The domain part of our parsed mail address (part after "@") inclusive our
78
         * top level domain (TLD). It is in its Unicode form.
79
         *
80
         * @return The domain part in Unicode.
81
         */
82
        public String getDomainPartUnicode() {
83
                return domainPartUnicode;
84
        }
85
 
86
        /**
87
         * The domain part of our parsed mail address (part after "@") inclusive our
88
         * top level domain (TLD). It is in its Punycode (ASCII) form.
89
         *
90
         * @return The domain part in Punycode.
91
         */
92
        public String getDomainPartPunycode() {
93
                return domainPartPunycode;
94
        }
95
 
96
        /**
97
         * The top level domain (COM, ORG, BIZ...) of our parsed mail address. The
98
         * dot is not included. It is in its Unicode form.
99
         *
100
         * @return The TLD in Unicode.
101
         */
102
        public String getTldUnicode() {
103
                return tldUnicode;
104
        }
105
 
106
        /**
107
         * The top level domain (COM, ORG, BIZ...) of our parsed mail address. The
108
         * dot is not included. It is in its Punycode form.
109
         *
110
         * @return The TLD in Punycode.
111
         */
112
        public String getTldPunycode() {
113
                return tldPunycode;
114
        }
115
 
116
        // Constructors
117
 
118
        /**
119
         * Creates an email address object out of an email address string.
120
         *
121
         * @param eMailAddress
122
         *            bare computer email address. e.g. roedyg@mindprod.com No
123
         *            "Roedy Green" <roedyg@mindprod.com> style addresses. No local
124
         *            addresses, e.g. roedy.
125
         * @throws InvalidMailAddressException
126
         */
127
        public EMailAddress(String eMailAddress) throws InvalidMailAddressException {
128
                super();
129
 
130
                if (eMailAddress == null) {
131
                        throw new InvalidMailAddressException();
132
                }
133
 
134
                // Zuerst trimmen (z.B. für Formulardaten) Wir splitten dann beim
135
                // At-Zeichen (@) und berücksichtigen ein escaped-At
136
                // (\@)
137
                String[] res = eMailAddress.trim().split("(?<!\\\\)@");
138
 
139
                // @-sign was not used once
140
                if (res.length != 2) {
141
                        throw new InvalidMailAddressException();
142
                }
143
 
144
                // Temporary we store the values here.
145
 
146
                String localPart = res[0];
147
                String domainPart = res[1];
148
 
149
                // We parse the local part.
150
 
151
                if (localPart == null)
152
                        localPart = "";
153
                this.localPart = localPart;
154
 
155
                // We parse the domainPart and allocate punycode and unicode fields.
156
 
157
                if (domainPart == null)
158
                        domainPart = "";
159
                if (isUnicode(domainPart)) {
160
                        this.domainPartUnicode = domainPart;
161
                        this.domainPartPunycode = IDN.toASCII(domainPart);
162
                } else /* if (isPunycode(domainPart)) */{
163
                        this.domainPartUnicode = IDN.toUnicode(domainPart);
164
                        this.domainPartPunycode = domainPart;
165
                }
166
 
167
                // We additionally parse the TLD and also determinate if it is punycode
168
                // or not.
169
 
170
                int dotIdx;
171
 
172
                dotIdx = this.domainPartUnicode.lastIndexOf('.');
173
                if (dotIdx >= 0) {
174
                        this.tldUnicode = this.domainPartUnicode.substring(dotIdx + 1);
175
                } else {
176
                        // We do not throw an exception here because it could be an email to
177
                        // a network computer or an IP address.
178
                        this.tldUnicode = "";
179
                }
180
 
181
                dotIdx = this.domainPartPunycode.lastIndexOf('.');
182
                if (dotIdx >= 0) {
183
                        this.tldPunycode = this.domainPartPunycode.substring(dotIdx + 1);
184
                } else {
185
                        // We do not throw an exception here because it could be an email to
186
                        // a network computer or an IP address.
187
                        this.tldPunycode = "";
188
                }
189
        }
190
 
191
        // Methods
192
 
193
        /**
194
         * Returns the email address with punycoded domain name and TLD. You should use
195
         * this method to send emails.
196
         *
197
         * @return The email address with punycoded domain name and TLD.
198
         */
199
        public String getMailAddressPunycodedDomain() {
200
                return this.localPart + "@" + this.domainPartPunycode;
201
        }
202
 
203
        /**
204
         * Returns the email address with internationalized domain names and TLD.
205
         *
206
         * @return The email address with internationalized domain name and TLD.
207
         */
208
        public String getMailAddressUnicode() {
209
                return this.localPart + "@" + this.domainPartUnicode;
210
        }
211
 
212
        /**
213
         * Returns a string which represents the mail address. If the constant
214
         * USE_UNICODE_AS_STANDARD is true, the internationalized domain names will
215
         * not translated into the corresponding Punycode. If false, then not.
216
         *
217
         * @return The string which represents the mail address. Warning! Since this
218
         *         method is rather designed to show a formatted mail address, it
219
         *         should NOT be used to send emails. Please only use this function
220
         *         if you want to output.
221
         */
222
        @Override
223
        public String toString() {
224
                if (USE_UNICODE_AS_STANDARD) {
225
                        return this.getMailAddressUnicode();
226
                } else {
227
                        return this.getMailAddressPunycodedDomain();
228
                }
229
        }
230
 
231
        /**
232
         * Checks if an object is equal to our email address object.
233
         *
234
         * @return Boolean which describes if it is equal or not.
235
         */
236
        @Override
237
        public boolean equals(Object obj) {
238
                // Initial checks
239
 
240
                if (this == obj)
241
                        return true;
242
                if (obj == null)
243
                        return false;
244
                if (obj.getClass() != getClass())
245
                        return false;
246
 
247
                // Compare the fields
248
 
249
                if (!this.domainPartPunycode
250
                                .equals(((EMailAddress) obj).domainPartPunycode)) {
251
                        return false;
252
                }
253
                if (!this.domainPartUnicode
254
                                .equals(((EMailAddress) obj).domainPartUnicode)) {
255
                        return false;
256
                }
257
                if (!this.localPart.equals(((EMailAddress) obj).localPart)) {
258
                        return false;
259
                }
260
                if (!this.tldUnicode.equals(((EMailAddress) obj).tldUnicode)) {
261
                        return false;
262
                }
263
                if (!this.tldPunycode.equals(((EMailAddress) obj).tldPunycode)) {
264
                        return false;
265
                }
266
 
267
                // Everything's fine ^^
268
 
269
                return true;
270
 
271
                // return this.toString().equals(obj.toString());
272
        }
273
 
274
        /**
275
         * Creates a deep copy of the email address object.
276
         *
277
         * @return A new instance of the email address object with the same
278
         *         properties.
279
         */
280
        @Override
281
        protected EMailAddress clone() throws CloneNotSupportedException {
282
                try {
283
                        return new EMailAddress(this.toString());
284
                } catch (InvalidMailAddressException e) {
285
                        return null;
286
                }
287
        }
288
 
289
        /**
290
         * Asks the mail syntax checker if the current mail address is valid or not.
291
         * Warning! This check is NOT performed automatically. There is no guarantee
292
         * that the syntax check is 100% correct. There might be mail address which
293
         * are valid but marked as invalid (because server disobeyed RFC rules etc)
294
         * and mail addresses which are invalid but marked valid (e.g. simply if
295
         * they were not assigned).
296
         *
297
         * @return Boolean which represents if the mail address is valid or not.
298
         */
299
        public boolean isSyntaxValid() {
300
                return MailSyntaxChecker.isMailValid(this);
301
        }
302
 
303
        // ---------- STATIC FUNCTIONS ----------
304
 
305
        /**
306
         * Determinates if a given string can be converted into Punycode.
307
         *
308
         * @param str
309
         *            The string which should be checked
310
         * @return Boolean which shows if the string is not yet punicoded.
311
         */
312
        protected static boolean isUnicode(String str) {
313
                if (str == null)
314
                        return false;
315
                return (!IDN.toASCII(str).equals(str));
316
        }
317
 
318
        /**
319
         * Determinates if a given string is in Punycode format.
320
         *
321
         * @param str
322
         *            The string which should be checked
323
         * @return Boolean which shows if the string is punycoded or not.
324
         */
325
        protected static boolean isPunycode(String str) {
326
                if (str == null)
327
                        return false;
328
                return (!IDN.toUnicode(str).equals(str));
329
        }
330
}