1. /*
  2. * Copyright 2002-2004 The Apache Software Foundation
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License");
  5. * you may not use this file except in compliance with the License.
  6. * You may obtain a copy of the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS,
  12. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. * See the License for the specific language governing permissions and
  14. * limitations under the License.
  15. *
  16. */
  17. package org.apache.tools.ant.taskdefs.email;
  18. /**
  19. * Holds an email address.
  20. *
  21. * @since Ant 1.5
  22. */
  23. public class EmailAddress {
  24. private String name;
  25. private String address;
  26. /** Creates an empty email address */
  27. public EmailAddress() {
  28. }
  29. /**
  30. * Creates a new email address based on the given string
  31. *
  32. * @param email the email address (with or without <>)
  33. * Acceptable forms include:
  34. * address
  35. * <address>
  36. * name <address>
  37. * <address> name
  38. * (name) address
  39. * address (name)
  40. */
  41. // Make a limited attempt to extract a sanitized name and email address
  42. // Algorithm based on the one found in Ant's MailMessage.java
  43. public EmailAddress(String email) {
  44. final int minLen = 9;
  45. int len = email.length();
  46. // shortcut for "<address>"
  47. if (len > minLen) {
  48. if ((email.charAt(0) == '<' || email.charAt(1) == '<')
  49. && (email.charAt(len - 1) == '>' || email.charAt(len - 2) == '>')) {
  50. this.address = trim(email, true);
  51. return;
  52. }
  53. }
  54. int paramDepth = 0;
  55. int start = 0;
  56. int end = 0;
  57. int nStart = 0;
  58. int nEnd = 0;
  59. for (int i = 0; i < len; i++) {
  60. char c = email.charAt(i);
  61. if (c == '(') {
  62. paramDepth++;
  63. if (start == 0) {
  64. end = i; // support "address (name)"
  65. nStart = i + 1;
  66. }
  67. } else if (c == ')') {
  68. paramDepth--;
  69. if (end == 0) {
  70. start = i + 1; // support "(name) address"
  71. nEnd = i;
  72. }
  73. } else if (paramDepth == 0 && c == '<') {
  74. if (start == 0) {
  75. nEnd = i;
  76. }
  77. start = i + 1;
  78. } else if (paramDepth == 0 && c == '>') {
  79. end = i;
  80. if (end != len - 1) {
  81. nStart = i + 1;
  82. }
  83. }
  84. }
  85. // DEBUG: System.out.println( email );
  86. if (end == 0) {
  87. end = len;
  88. }
  89. // DEBUG: System.out.println( "address: " + start + " " + end );
  90. if (nEnd == 0) {
  91. nEnd = len;
  92. }
  93. // DEBUG: System.out.println( "name: " + nStart + " " + nEnd );
  94. this.address = trim(email.substring(start, end), true);
  95. this.name = trim(email.substring(nStart, nEnd), false);
  96. // if the two substrings are longer than the original, then name
  97. // contains address - so reset the name to null
  98. if (this.name.length() + this.address.length() > len) {
  99. this.name = null;
  100. }
  101. }
  102. /**
  103. * A specialised trim() that trims whitespace,
  104. * '(', ')', '"', '<', '>' from the start and end of strings
  105. */
  106. private String trim(String t, boolean trimAngleBrackets) {
  107. int start = 0;
  108. int end = t.length();
  109. boolean trim = false;
  110. do {
  111. trim = false;
  112. if (t.charAt(end - 1) == ')'
  113. || (t.charAt(end - 1) == '>' && trimAngleBrackets)
  114. || (t.charAt(end - 1) == '"' && t.charAt(end - 2) != '\\')
  115. || t.charAt(end - 1) <= '\u0020') {
  116. trim = true;
  117. end--;
  118. }
  119. if (t.charAt(start) == '('
  120. || (t.charAt(start) == '<' && trimAngleBrackets)
  121. || t.charAt(start) == '"'
  122. || t.charAt(start) <= '\u0020') {
  123. trim = true;
  124. start++;
  125. }
  126. } while (trim);
  127. return t.substring(start, end);
  128. }
  129. /**
  130. * Sets the personal / display name of the address
  131. *
  132. * @param name the display name
  133. */
  134. public void setName(String name) {
  135. this.name = name;
  136. }
  137. /**
  138. * Sets the email address
  139. *
  140. * @param address the actual email address (without <>)
  141. */
  142. public void setAddress(String address) {
  143. this.address = address;
  144. }
  145. /**
  146. * Constructs a string "name <address>" or "address"
  147. *
  148. * @return a string representation of the address
  149. */
  150. public String toString() {
  151. if (name == null) {
  152. return address;
  153. } else {
  154. return name + " <" + address + ">";
  155. }
  156. }
  157. /**
  158. * Returns the address
  159. *
  160. * @return the address part
  161. */
  162. public String getAddress() {
  163. return address;
  164. }
  165. /**
  166. * Returns the display name
  167. *
  168. * @return the display name part
  169. */
  170. public String getName() {
  171. return name;
  172. }
  173. }