All Downloads are FREE. Search and download functionalities are using the official Maven repository.

panda.net.dns.MXLookup Maven / Gradle / Ivy

package panda.net.dns;

import java.util.ArrayList;
import java.util.Hashtable;
import java.util.List;
import java.util.Map;

import javax.naming.NamingException;
import javax.naming.directory.Attribute;
import javax.naming.directory.Attributes;
import javax.naming.directory.DirContext;
import javax.naming.directory.InitialDirContext;

import panda.lang.Collections;
import panda.lang.Strings;
import panda.lang.collection.ExpireMap;
import panda.lang.collection.LRUMap;
import panda.lang.time.DateTimes;
import panda.log.Log;
import panda.log.Logs;

/**
 * A utility class for mx records lookup.
 */
public class MXLookup {
	private static final Log log = Logs.getLog(MXLookup.class);
	
	/**
	 * default expire time: 30m
	 */
	public static final long DEFAULT_CACHE_MAXAGE = DateTimes.MS_MINUTE * 30;
	
	/**
	 * default cache limit: 100
	 */
	public static final int DEFAULT_CACHE_LIMIT = 100;
	
	protected static Map> cache;

	/**
	 * init cache
	 * @param limit limit count
	 * @param expire expire (millisecond)
	 */
	public static synchronized void initCache(int limit, long expire) {
		ExpireMap> em = new ExpireMap>(new LRUMap>(limit), expire);
		cache = Collections.synchronizedMap(em);
	}

	private static synchronized List getCachedHosts(String hostname) {
		return cache == null ? null : cache.get(hostname);
	}

	private static synchronized void putHostsToCache(String hostname, List hosts) {
		if (cache == null) {
			initCache(DEFAULT_CACHE_LIMIT, DEFAULT_CACHE_MAXAGE);
		}
		cache.put(hostname, hosts);
	}

	/**
	 * lookup mx records by hostname
	 * @param hostname host name
	 * @return server list
	 * @throws NamingException if a naming error occurs
	 */
	public static List lookup(String hostname) throws NamingException {
		List hosts = getCachedHosts(hostname);
		if (Collections.isNotEmpty(hosts)) {
			return hosts;
		}
		
		if (log.isDebugEnabled()) {
			log.debug("MX Lookup for " + hostname);
		}

		Hashtable env = new Hashtable();
		env.put("java.naming.factory.initial", "com.sun.jndi.dns.DnsContextFactory");

		DirContext ictx = new InitialDirContext(env);

		Attributes attrs = ictx.getAttributes(hostname, new String[] { "MX" });
		Attribute attr = attrs.get("MX");

		// if we don't have an MX record, try the machine itself
		if ((attr == null) || (attr.size() == 0)) {
			attrs = ictx.getAttributes(hostname, new String[] { "A" });
			attr = attrs.get("A");
			if (attr == null) {
				throw new NamingException("No match for name '" + hostname + "'");
			}
		}

		hosts = new ArrayList(attr.size());
		for (int i = 0; i < attr.size(); i++) {
			String[] ss = Strings.split((String)attr.get(i), ' ');
			if (ss.length == 1) {
				hosts.add(ss[0]);
			}
			else if (ss[1].endsWith(".")) {
				hosts.add(ss[1].substring(0, (ss[1].length() - 1)));
			}
			else {
				hosts.add(ss[1]);
			}
		}

		putHostsToCache(hostname, hosts);
		return hosts;
	}
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy