001 /****************************************************************
002 * Licensed to the Apache Software Foundation (ASF) under one *
003 * or more contributor license agreements. See the NOTICE file *
004 * distributed with this work for additional information *
005 * regarding copyright ownership. The ASF licenses this file *
006 * to you under the Apache License, Version 2.0 (the *
007 * "License"); you may not use this file except in compliance *
008 * with the License. You may obtain a copy of the License at *
009 * *
010 * http://www.apache.org/licenses/LICENSE-2.0 *
011 * *
012 * Unless required by applicable law or agreed to in writing, *
013 * software distributed under the License is distributed on an *
014 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY *
015 * KIND, either express or implied. See the License for the *
016 * specific language governing permissions and limitations *
017 * under the License. *
018 ****************************************************************/
019
020 package org.apache.james.mime4j.field.address;
021
022 import org.apache.james.mime4j.codec.EncoderUtil;
023 import org.apache.james.mime4j.dom.address.Address;
024 import org.apache.james.mime4j.dom.address.Group;
025 import org.apache.james.mime4j.dom.address.Mailbox;
026
027 /**
028 * Default formatter for {@link Address} and its subclasses.
029 */
030 public class AddressFormatter {
031
032 public static final AddressFormatter DEFAULT = new AddressFormatter();
033
034 protected AddressFormatter() {
035 super();
036 }
037
038 /**
039 * Formats the address as a human readable string, not including the route.
040 * The resulting string is intended for display purposes only and cannot be
041 * used for transport purposes.
042 *
043 * For example, if the unparsed address was
044 *
045 * <"Joe Cheng"@joecheng.com>
046 *
047 * this method would return
048 *
049 * <Joe Cheng@joecheng.com>
050 *
051 * which is not valid for transport; the local part would need to be
052 * re-quoted.
053 *
054 * @param includeRoute
055 * <code>true</code> if the route should be included if it
056 * exists, <code>false</code> otherwise.
057 */
058 public void format(final StringBuilder sb, final Address address, boolean includeRoute) {
059 if (address == null) {
060 return;
061 }
062 if (address instanceof Mailbox) {
063 format(sb, (Mailbox) address, includeRoute);
064 } else if (address instanceof Group) {
065 format(sb, (Group) address, includeRoute);
066 } else {
067 throw new IllegalArgumentException("Unsuppported Address class: " + address.getClass());
068 }
069 }
070
071 /**
072 * Returns a string representation of this address that can be used for
073 * transport purposes. The route is never included in this representation
074 * because routes are obsolete and RFC 5322 states that obsolete syntactic
075 * forms MUST NOT be generated.
076 */
077 public void encode(final StringBuilder sb, final Address address) {
078 if (address == null) {
079 return;
080 }
081 if (address instanceof Mailbox) {
082 encode(sb, (Mailbox) address);
083 } else if (address instanceof Group) {
084 encode(sb, (Group) address);
085 } else {
086 throw new IllegalArgumentException("Unsuppported Address class: " + address.getClass());
087 }
088 }
089
090 public void format(final StringBuilder sb, final Mailbox mailbox, boolean includeRoute) {
091 if (sb == null) {
092 throw new IllegalArgumentException("StringBuilder may not be null");
093 }
094 if (mailbox == null) {
095 throw new IllegalArgumentException("Mailbox may not be null");
096 }
097 includeRoute &= mailbox.getRoute() != null;
098 boolean includeAngleBrackets = mailbox.getName() != null || includeRoute;
099 if (mailbox.getName() != null) {
100 sb.append(mailbox.getName());
101 sb.append(' ');
102 }
103 if (includeAngleBrackets) {
104 sb.append('<');
105 }
106 if (includeRoute) {
107 sb.append(mailbox.getRoute().toRouteString());
108 sb.append(':');
109 }
110 sb.append(mailbox.getLocalPart());
111 if (mailbox.getDomain() != null) {
112 sb.append('@');
113 sb.append(mailbox.getDomain());
114 }
115 if (includeAngleBrackets) {
116 sb.append('>');
117 }
118 }
119
120 public String format(final Mailbox mailbox, boolean includeRoute) {
121 StringBuilder sb = new StringBuilder();
122 format(sb, mailbox, includeRoute);
123 return sb.toString();
124 }
125
126 public void encode(final StringBuilder sb, final Mailbox mailbox) {
127 if (sb == null) {
128 throw new IllegalArgumentException("StringBuilder may not be null");
129 }
130 if (mailbox == null) {
131 throw new IllegalArgumentException("Mailbox may not be null");
132 }
133 if (mailbox.getName() != null) {
134 sb.append(EncoderUtil.encodeAddressDisplayName(mailbox.getName()));
135 sb.append(" <");
136 }
137 sb.append(EncoderUtil.encodeAddressLocalPart(mailbox.getLocalPart()));
138 // domain = dot-atom / domain-literal
139 // domain-literal = [CFWS] "[" *([FWS] dtext) [FWS] "]" [CFWS]
140 // dtext = %d33-90 / %d94-126
141 if (mailbox.getDomain() != null) {
142 sb.append('@');
143 sb.append(mailbox.getDomain());
144 }
145 if (mailbox.getName() != null) {
146 sb.append('>');
147 }
148 }
149
150 public String encode(final Mailbox mailbox) {
151 StringBuilder sb = new StringBuilder();
152 encode(sb, mailbox);
153 return sb.toString();
154 }
155
156 public void format(final StringBuilder sb, final Group group, boolean includeRoute) {
157 if (sb == null) {
158 throw new IllegalArgumentException("StringBuilder may not be null");
159 }
160 if (group == null) {
161 throw new IllegalArgumentException("Group may not be null");
162 }
163 sb.append(group.getName());
164 sb.append(':');
165
166 boolean first = true;
167 for (Mailbox mailbox : group.getMailboxes()) {
168 if (first) {
169 first = false;
170 } else {
171 sb.append(',');
172 }
173 sb.append(' ');
174 format(sb, mailbox, includeRoute);
175 }
176 sb.append(";");
177 }
178
179 public String format(final Group group, boolean includeRoute) {
180 StringBuilder sb = new StringBuilder();
181 format(sb, group, includeRoute);
182 return sb.toString();
183 }
184
185 public void encode(final StringBuilder sb, final Group group) {
186 if (sb == null) {
187 throw new IllegalArgumentException("StringBuilder may not be null");
188 }
189 if (group == null) {
190 throw new IllegalArgumentException("Group may not be null");
191 }
192 sb.append(EncoderUtil.encodeAddressDisplayName(group.getName()));
193 sb.append(':');
194 boolean first = true;
195 for (Mailbox mailbox : group.getMailboxes()) {
196 if (first) {
197 first = false;
198 } else {
199 sb.append(',');
200 }
201
202 sb.append(' ');
203 encode(sb, mailbox);
204 }
205 sb.append(';');
206 }
207
208 public String encode(final Group group) {
209 StringBuilder sb = new StringBuilder();
210 encode(sb, group);
211 return sb.toString();
212 }
213
214 }