001: /*
002: * MailAddress.java
003: *
004: * Copyright (C) 2000-2003 Peter Graves
005: * $Id: MailAddress.java,v 1.4 2003/08/13 18:25:17 piso Exp $
006: *
007: * This program is free software; you can redistribute it and/or
008: * modify it under the terms of the GNU General Public License
009: * as published by the Free Software Foundation; either version 2
010: * of the License, or (at your option) any later version.
011: *
012: * This program is distributed in the hope that it will be useful,
013: * but WITHOUT ANY WARRANTY; without even the implied warranty of
014: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
015: * GNU General Public License for more details.
016: *
017: * You should have received a copy of the GNU General Public License
018: * along with this program; if not, write to the Free Software
019: * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
020: */
021:
022: package org.armedbear.j.mail;
023:
024: import java.io.Serializable;
025: import java.util.ArrayList;
026: import org.armedbear.j.FastStringBuffer;
027:
028: public final class MailAddress implements Serializable {
029: private final String personal;
030: private final String encodedPersonal;
031: private final String address;
032:
033: public MailAddress(String encodedPersonal, String address) {
034: if (encodedPersonal != null && encodedPersonal.length() > 0) {
035: // Remove enclosing quotes if any.
036: // Handle cases like "'mikol@onebox.com'" where the actual string
037: // is enclosed in both single and double quotes.
038: char c = encodedPersonal.charAt(0);
039: if (c == '"' || c == '\'') {
040: int length = encodedPersonal.length();
041: if (length >= 2) {
042: if (encodedPersonal.charAt(length - 1) == c) {
043: encodedPersonal = encodedPersonal.substring(1,
044: length - 1);
045: length -= 2;
046: if (length >= 2) {
047: c = encodedPersonal.charAt(0);
048: if (c == '"' || c == '\'') {
049: if (encodedPersonal.charAt(length - 1) == c) {
050: encodedPersonal = encodedPersonal
051: .substring(1, length - 1);
052: }
053: }
054: }
055: }
056: }
057: }
058: this .encodedPersonal = encodedPersonal.intern();
059: personal = RFC2047.decode(encodedPersonal).trim().intern();
060: } else {
061: this .encodedPersonal = null;
062: personal = null;
063: }
064: if (address != null && address.length() > 0) {
065: if (address.charAt(0) == '<') {
066: final int length = address.length();
067: if (length >= 2) {
068: if (address.charAt(length - 1) == '>')
069: address = address.substring(1, length - 1);
070: }
071: }
072: this .address = address.intern();
073: } else
074: this .address = null;
075: }
076:
077: public final String getPersonal() {
078: return personal;
079: }
080:
081: public final String getEncodedPersonal() {
082: return encodedPersonal;
083: }
084:
085: public final String getAddress() {
086: return address;
087: }
088:
089: public String toString() {
090: FastStringBuffer sb = new FastStringBuffer();
091: if (personal != null && personal.length() > 0) {
092: if (personal.indexOf(',') >= 0
093: || personal.indexOf('.') >= 0) {
094: sb.append('"');
095: sb.append(personal);
096: sb.append('"');
097: } else
098: sb.append(personal);
099: if (address != null && address.length() > 0) {
100: sb.append(" <");
101: sb.append(address);
102: sb.append('>');
103: }
104: } else if (address != null && address.length() > 0)
105: sb.append(address);
106: return sb.toString();
107: }
108:
109: public String toEncodedString() {
110: if (encodedPersonal == null || encodedPersonal.length() == 0)
111: return toString();
112: FastStringBuffer sb = new FastStringBuffer();
113: if (encodedPersonal.indexOf(',') >= 0
114: || encodedPersonal.indexOf('.') >= 0) {
115: sb.append('"');
116: sb.append(encodedPersonal);
117: sb.append('"');
118: } else
119: sb.append(encodedPersonal);
120: if (address != null && address.length() > 0) {
121: sb.append(" <");
122: sb.append(address);
123: sb.append('>');
124: }
125: return sb.toString();
126: }
127:
128: public boolean equals(Object o) {
129: if (this == o)
130: return true;
131: if (o instanceof MailAddress) {
132: MailAddress ma = (MailAddress) o;
133: if (personal != ma.personal)
134: return false;
135: if (encodedPersonal != ma.encodedPersonal)
136: return false;
137: if (address != ma.address)
138: return false;
139: return true;
140: } else
141: return false;
142: }
143:
144: public final boolean matches(String pattern) {
145: if (personal != null)
146: if (personal.indexOf(pattern) >= 0)
147: return true; // Personal name matches.
148: if (address != null)
149: if (address.indexOf(pattern) >= 0)
150: return true; // Address matches.
151: return false;
152: }
153:
154: // Pattern is already lower case.
155: public final boolean matchesIgnoreCase(String pattern) {
156: if (personal != null)
157: if (personal.toLowerCase().indexOf(pattern) >= 0)
158: return true; // Personal name matches.
159: if (address != null)
160: if (address.toLowerCase().indexOf(pattern) >= 0)
161: return true; // Address matches.
162: return false;
163: }
164:
165: public final boolean matches(MailAddress a) {
166: // Personal name must be exact match.
167: if (personal != null && personal.equals(a.personal))
168: return true;
169: else if (address != null && address.equalsIgnoreCase(a.address))
170: return true;
171: else
172: return false;
173: }
174:
175: public final boolean addressMatches(MailAddress a) {
176: if (address != null && address.equalsIgnoreCase(a.address))
177: return true;
178: else
179: return false;
180: }
181:
182: public static MailAddress parseAddress(String s) {
183: int index = s.lastIndexOf('<');
184: if (index >= 0) {
185: String encodedPersonal = s.substring(0, index).trim();
186: String address = s.substring(index);
187: return new MailAddress(encodedPersonal, address);
188: }
189: index = s.indexOf('(');
190: if (index >= 0) {
191: String address = s.substring(0, index).trim();
192: if (address.indexOf('@') >= 0) {
193: int begin = index + 1;
194: int end = s.indexOf(')', begin);
195: if (end >= 0) {
196: String encodedPersonal = s.substring(begin, end)
197: .trim();
198: return new MailAddress(encodedPersonal, address);
199: }
200: }
201: }
202: return new MailAddress(null, s);
203: }
204:
205: public static MailAddress[] parseAddresses(String input) {
206: if (input == null)
207: return null;
208: input = input.trim();
209: if (input.length() == 0)
210: return null;
211: ArrayList addresses = new ArrayList();
212: FastStringBuffer sb = new FastStringBuffer();
213: boolean inQuote = false;
214: final int limit = input.length();
215: for (int i = 0; i < limit; i++) {
216: char c = input.charAt(i);
217: switch (c) {
218: case '"':
219: inQuote = !inQuote;
220: sb.append(c);
221: break;
222: case ',':
223: if (inQuote) {
224: // A comma inside a quoted string is just an ordinary
225: // character.
226: sb.append(c);
227: } else {
228: // Otherwise a comma marks the end of the address.
229: String s = sb.toString().trim();
230: if (s.length() > 0) {
231: MailAddress address = parseAddress(s);
232: if (address != null)
233: addresses.add(address);
234: }
235: sb.setLength(0);
236: }
237: break;
238: default:
239: sb.append(c);
240: break;
241: }
242: }
243: if (sb.length() > 0) {
244: String s = sb.toString().trim();
245: if (s.length() > 0) {
246: MailAddress address = parseAddress(s);
247: if (address != null)
248: addresses.add(address);
249: }
250: }
251: if (addresses.size() == 0)
252: return null;
253: MailAddress[] array = new MailAddress[addresses.size()];
254: return (MailAddress[]) addresses.toArray(array);
255: }
256: }
|