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.domainlist.lib;
021    
022    import java.net.InetAddress;
023    import java.net.UnknownHostException;
024    import java.util.ArrayList;
025    import java.util.Iterator;
026    import java.util.List;
027    import java.util.Locale;
028    
029    import javax.annotation.Resource;
030    
031    import org.apache.commons.configuration.ConfigurationException;
032    import org.apache.commons.configuration.HierarchicalConfiguration;
033    import org.apache.james.dnsservice.api.DNSService;
034    import org.apache.james.domainlist.api.DomainList;
035    import org.apache.james.domainlist.api.DomainListException;
036    import org.apache.james.lifecycle.api.Configurable;
037    import org.apache.james.lifecycle.api.LogEnabled;
038    import org.slf4j.Logger;
039    
040    /**
041     * All implementations of the DomainList interface should extends this abstract
042     * class
043     */
044    public abstract class AbstractDomainList implements DomainList, LogEnabled, Configurable {
045        private DNSService dns;
046        private boolean autoDetect = true;
047        private boolean autoDetectIP = true;
048        private Logger logger;
049        private String defaultDomain;
050    
051        @Resource(name = "dnsservice")
052        public void setDNSService(DNSService dns) {
053            this.dns = dns;
054        }
055    
056        public void setLog(Logger logger) {
057            this.logger = logger;
058        }
059    
060        protected Logger getLogger() {
061            return logger;
062        }
063    
064        /**
065         * @see org.apache.james.lifecycle.api.Configurable#configure(HierarchicalConfiguration)
066         */
067        public void configure(HierarchicalConfiguration config) throws ConfigurationException {
068            defaultDomain = config.getString("defaultDomain", "localhost");
069    
070            setAutoDetect(config.getBoolean("autodetect", true));
071            setAutoDetectIP(config.getBoolean("autodetectIP", true));
072        }
073    
074        /**
075         * @see org.apache.james.domainlist.api.DomainList#getDefaultDomain()
076         */
077        public String getDefaultDomain() throws DomainListException {
078            return defaultDomain;
079        }
080    
081        /**
082         * @see org.apache.james.domainlist.api.DomainList#getDomains()
083         */
084        public String[] getDomains() throws DomainListException {
085            List<String> domains = getDomainListInternal();
086            if (domains != null) {
087    
088                String hostName = null;
089                try {
090                    hostName = getDNSServer().getHostName(getDNSServer().getLocalHost());
091                } catch (UnknownHostException ue) {
092                    hostName = "localhost";
093                }
094    
095                getLogger().info("Local host is: " + hostName);
096    
097                if (autoDetect == true && (!hostName.equals("localhost"))) {
098                    domains.add(hostName.toLowerCase(Locale.US));
099                }
100    
101                if (autoDetectIP == true) {
102                    domains.addAll(getDomainsIP(domains, dns, getLogger()));
103                }
104    
105                if (getLogger().isInfoEnabled()) {
106                    for (Iterator<String> i = domains.iterator(); i.hasNext();) {
107                        getLogger().debug("Handling mail for: " + i.next());
108                    }
109                }
110                if (domains.isEmpty()) {
111                    return null;
112                } else {
113                    return domains.toArray(new String[domains.size()]);
114                }
115            } else {
116                return null;
117            }
118        }
119    
120        /**
121         * Return a List which holds all ipAddress of the domains in the given List
122         * 
123         * @param domains
124         *            List of domains
125         * @return domainIP List of ipaddress for domains
126         */
127        private static List<String> getDomainsIP(List<String> domains, DNSService dns, Logger log) {
128            List<String> domainIP = new ArrayList<String>();
129            if (domains.size() > 0) {
130                for (int i = 0; i < domains.size(); i++) {
131                    List<String> domList = getDomainIP(domains.get(i).toString(), dns, log);
132    
133                    for (int i2 = 0; i2 < domList.size(); i2++) {
134                        if (domainIP.contains(domList.get(i2)) == false) {
135                            domainIP.add(domList.get(i2));
136                        }
137                    }
138                }
139            }
140            return domainIP;
141        }
142    
143        /**
144         * @see #getDomainsIP(List, DNSService, Logger)
145         */
146        private static List<String> getDomainIP(String domain, DNSService dns, Logger log) {
147            List<String> domainIP = new ArrayList<String>();
148            try {
149                InetAddress[] addrs = dns.getAllByName(domain);
150                for (int j = 0; j < addrs.length; j++) {
151                    String ip = addrs[j].getHostAddress();
152                    if (domainIP.contains(ip) == false) {
153                        domainIP.add(ip);
154                    }
155                }
156            } catch (UnknownHostException e) {
157                log.error("Cannot get IP address(es) for " + domain);
158            }
159            return domainIP;
160        }
161    
162        /**
163         * Set to true to autodetect the hostname of the host on which james is
164         * running, and add this to the domain service Default is true
165         * 
166         * @param autoDetect
167         *            set to <code>false</code> for disable
168         */
169        public synchronized void setAutoDetect(boolean autoDetect) {
170            getLogger().info("Set autodetect to: " + autoDetect);
171            this.autoDetect = autoDetect;
172        }
173    
174        /**
175         * Set to true to lookup the ipaddresses for each given domain and add these
176         * to the domain service Default is true
177         * 
178         * @param autoDetectIP
179         *            set to <code>false</code> for disable
180         */
181        public synchronized void setAutoDetectIP(boolean autoDetectIP) {
182            getLogger().info("Set autodetectIP to: " + autoDetectIP);
183            this.autoDetectIP = autoDetectIP;
184        }
185    
186        /**
187         * Return dnsServer
188         * 
189         * @return dns
190         */
191        protected DNSService getDNSServer() {
192            return dns;
193        }
194    
195        /**
196         * Return domainList
197         * 
198         * @return List
199         */
200        protected abstract List<String> getDomainListInternal() throws DomainListException;
201    
202    }