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.dom.address;
021    
022    import java.util.Collections;
023    import java.util.List;
024    import java.util.Locale;
025    
026    import org.apache.james.mime4j.util.LangUtils;
027    
028    /**
029     * Represents a single e-mail address.
030     */
031    public class Mailbox extends Address {
032    
033        private static final long serialVersionUID = 1L;
034    
035        private static final DomainList EMPTY_ROUTE_LIST = new DomainList(
036                Collections.<String> emptyList(), true);
037    
038        private final String name;
039        private final DomainList route;
040        private final String localPart;
041        private final String domain;
042    
043        /**
044         * Creates a named mailbox with a route. Routes are obsolete.
045         *
046         * @param name
047         *            the name of the e-mail address. May be <code>null</code>.
048         * @param route
049         *            The zero or more domains that make up the route. May be
050         *            <code>null</code>.
051         * @param localPart
052         *            The part of the e-mail address to the left of the "@".
053         * @param domain
054         *            The part of the e-mail address to the right of the "@".
055         */
056        public Mailbox(String name, DomainList route, String localPart,
057                String domain) {
058            if (localPart == null)
059                throw new IllegalArgumentException();
060    
061            this.name = name == null || name.length() == 0 ? null : name;
062            this.route = route == null ? EMPTY_ROUTE_LIST : route;
063            this.localPart = localPart;
064            this.domain = domain == null || domain.length() == 0 ? null : domain;
065        }
066    
067        /**
068         * Creates a named mailbox based on an unnamed mailbox. Package private;
069         * internally used by Builder.
070         */
071        Mailbox(String name, Mailbox baseMailbox) {
072            this(name, baseMailbox.getRoute(), baseMailbox.getLocalPart(),
073                    baseMailbox.getDomain());
074        }
075    
076        /**
077         * Creates an unnamed mailbox without a route. Routes are obsolete.
078         *
079         * @param localPart
080         *            The part of the e-mail address to the left of the "@".
081         * @param domain
082         *            The part of the e-mail address to the right of the "@".
083         */
084        public Mailbox(String localPart, String domain) {
085            this(null, null, localPart, domain);
086        }
087    
088        /**
089         * Creates an unnamed mailbox with a route. Routes are obsolete.
090         *
091         * @param route
092         *            The zero or more domains that make up the route. May be
093         *            <code>null</code>.
094         * @param localPart
095         *            The part of the e-mail address to the left of the "@".
096         * @param domain
097         *            The part of the e-mail address to the right of the "@".
098         */
099        public Mailbox(DomainList route, String localPart, String domain) {
100            this(null, route, localPart, domain);
101        }
102    
103        /**
104         * Creates a named mailbox without a route. Routes are obsolete.
105         *
106         * @param name
107         *            the name of the e-mail address. May be <code>null</code>.
108         * @param localPart
109         *            The part of the e-mail address to the left of the "@".
110         * @param domain
111         *            The part of the e-mail address to the right of the "@".
112         */
113        public Mailbox(String name, String localPart, String domain) {
114            this(name, null, localPart, domain);
115        }
116    
117        /**
118         * Returns the name of the mailbox or <code>null</code> if it does not
119         * have a name.
120         */
121        public String getName() {
122            return name;
123        }
124    
125        /**
126         * Returns the route list. If the mailbox does not have a route an empty
127         * domain list is returned.
128         */
129        public DomainList getRoute() {
130            return route;
131        }
132    
133        /**
134         * Returns the left part of the e-mail address (before "@").
135         */
136        public String getLocalPart() {
137            return localPart;
138        }
139    
140        /**
141         * Returns the right part of the e-mail address (after "@").
142         */
143        public String getDomain() {
144            return domain;
145        }
146    
147        /**
148         * Returns the address in the form <i>localPart@domain</i>.
149         *
150         * @return the address part of this mailbox.
151         */
152        public String getAddress() {
153            if (domain == null) {
154                return localPart;
155            } else {
156                return localPart + '@' + domain;
157            }
158        }
159    
160        @Override
161        protected final void doAddMailboxesTo(List<Mailbox> results) {
162            results.add(this);
163        }
164    
165        @Override
166        public int hashCode() {
167            int hash = LangUtils.HASH_SEED;
168            hash = LangUtils.hashCode(hash, this.localPart);
169            hash = LangUtils.hashCode(hash, this.domain != null ?
170                    this.domain.toLowerCase(Locale.US) : null);
171            return hash;
172        }
173    
174        /**
175         * Indicates whether some other object is "equal to" this mailbox.
176         * <p>
177         * An object is considered to be equal to this mailbox if it is an instance
178         * of class <code>Mailbox</code> that holds the same address as this one.
179         * The domain is considered to be case-insensitive but the local-part is not
180         * (because of RFC 5321: <cite>the local-part of a mailbox MUST BE treated
181         * as case sensitive</cite>).
182         *
183         * @param obj
184         *            the object to test for equality.
185         * @return <code>true</code> if the specified object is a
186         *         <code>Mailbox</code> that holds the same address as this one.
187         */
188        @Override
189        public boolean equals(Object obj) {
190            if (obj == this)
191                return true;
192            if (!(obj instanceof Mailbox))
193                return false;
194            Mailbox that = (Mailbox) obj;
195            return LangUtils.equals(this.localPart, that.localPart) &&
196                LangUtils.equalsIgnoreCase(this.domain, that.domain);
197        }
198    
199        @Override
200        public String toString() {
201            return getAddress();
202        }
203    
204    }