Subversion Repositories javautils

Rev

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