001: /*
002: * Licensed to the Apache Software Foundation (ASF) under one or more
003: * contributor license agreements. See the NOTICE file distributed with
004: * this work for additional information regarding copyright ownership.
005: * The ASF licenses this file to You under the Apache License, Version 2.0
006: * (the "License"); you may not use this file except in compliance with
007: * the License. You may obtain a copy of the License at
008: *
009: * http://www.apache.org/licenses/LICENSE-2.0
010: *
011: * Unless required by applicable law or agreed to in writing, software
012: * distributed under the License is distributed on an "AS IS" BASIS,
013: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014: * See the License for the specific language governing permissions and
015: * limitations under the License.
016: *
017: */
018: package org.apache.tools.ant.taskdefs.email;
019:
020: /**
021: * Holds an email address.
022: *
023: * @since Ant 1.5
024: */
025: public class EmailAddress {
026: private String name;
027: private String address;
028:
029: /** Creates an empty email address */
030: public EmailAddress() {
031: }
032:
033: /**
034: * Creates a new email address based on the given string
035: *
036: * @param email the email address (with or without <>)
037: * Acceptable forms include:
038: * address
039: * <address>
040: * name <address>
041: * <address> name
042: * (name) address
043: * address (name)
044: */
045: // Make a limited attempt to extract a sanitized name and email address
046: // Algorithm based on the one found in Ant's MailMessage.java
047: public EmailAddress(String email) {
048: final int minLen = 9;
049: int len = email.length();
050:
051: // shortcut for "<address>"
052: if (len > minLen) {
053: if ((email.charAt(0) == '<' || email.charAt(1) == '<')
054: && (email.charAt(len - 1) == '>' || email
055: .charAt(len - 2) == '>')) {
056: this .address = trim(email, true);
057: return;
058: }
059: }
060:
061: int paramDepth = 0;
062: int start = 0;
063: int end = 0;
064: int nStart = 0;
065: int nEnd = 0;
066:
067: for (int i = 0; i < len; i++) {
068: char c = email.charAt(i);
069: if (c == '(') {
070: paramDepth++;
071: if (start == 0) {
072: end = i; // support "address (name)"
073: nStart = i + 1;
074: }
075: } else if (c == ')') {
076: paramDepth--;
077: if (end == 0) {
078: start = i + 1; // support "(name) address"
079: nEnd = i;
080: }
081: } else if (paramDepth == 0 && c == '<') {
082: if (start == 0) {
083: nEnd = i;
084: }
085: start = i + 1;
086: } else if (paramDepth == 0 && c == '>') {
087: end = i;
088: if (end != len - 1) {
089: nStart = i + 1;
090: }
091: }
092: }
093:
094: // DEBUG: System.out.println( email );
095: if (end == 0) {
096: end = len;
097: }
098: // DEBUG: System.out.println( "address: " + start + " " + end );
099: if (nEnd == 0) {
100: nEnd = len;
101: }
102: // DEBUG: System.out.println( "name: " + nStart + " " + nEnd );
103:
104: this .address = trim(email.substring(start, end), true);
105: this .name = trim(email.substring(nStart, nEnd), false);
106:
107: // if the two substrings are longer than the original, then name
108: // contains address - so reset the name to null
109: if (this .name.length() + this .address.length() > len) {
110: this .name = null;
111: }
112: }
113:
114: /**
115: * A specialised trim() that trims whitespace,
116: * '(', ')', '"', '<', '>' from the start and end of strings
117: */
118: private String trim(String t, boolean trimAngleBrackets) {
119: int start = 0;
120: int end = t.length();
121: boolean trim = false;
122: do {
123: trim = false;
124: if (t.charAt(end - 1) == ')'
125: || (t.charAt(end - 1) == '>' && trimAngleBrackets)
126: || (t.charAt(end - 1) == '"' && t.charAt(end - 2) != '\\')
127: || t.charAt(end - 1) <= '\u0020') {
128: trim = true;
129: end--;
130: }
131: if (t.charAt(start) == '('
132: || (t.charAt(start) == '<' && trimAngleBrackets)
133: || t.charAt(start) == '"'
134: || t.charAt(start) <= '\u0020') {
135: trim = true;
136: start++;
137: }
138: } while (trim);
139: return t.substring(start, end);
140: }
141:
142: /**
143: * Sets the personal / display name of the address
144: *
145: * @param name the display name
146: */
147: public void setName(String name) {
148: this .name = name;
149: }
150:
151: /**
152: * Sets the email address
153: *
154: * @param address the actual email address (without <>)
155: */
156: public void setAddress(String address) {
157: this .address = address;
158: }
159:
160: /**
161: * Constructs a string "name <address>" or "address"
162: *
163: * @return a string representation of the address
164: */
165: public String toString() {
166: if (name == null) {
167: return address;
168: } else {
169: return name + " <" + address + ">";
170: }
171: }
172:
173: /**
174: * Returns the address
175: *
176: * @return the address part
177: */
178: public String getAddress() {
179: return address;
180: }
181:
182: /**
183: * Returns the display name
184: *
185: * @return the display name part
186: */
187: public String getName() {
188: return name;
189: }
190: }
|