001/** 002 * 003 * Copyright 2013-2014 Florian Schmaus 004 * 005 * Licensed under the Apache License, Version 2.0 (the "License"); 006 * you may not use this file except in compliance with the License. 007 * You may obtain a copy of the License at 008 * 009 * http://www.apache.org/licenses/LICENSE-2.0 010 * 011 * Unless required by applicable law or agreed to in writing, software 012 * distributed under the License is distributed on an "AS IS" BASIS, 013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 014 * See the License for the specific language governing permissions and 015 * limitations under the License. 016 */ 017package org.jivesoftware.smack.util.dns.javax; 018 019import java.util.ArrayList; 020import java.util.Collections; 021import java.util.Hashtable; 022import java.util.List; 023 024import javax.naming.NamingEnumeration; 025import javax.naming.NamingException; 026import javax.naming.directory.Attribute; 027import javax.naming.directory.Attributes; 028import javax.naming.directory.DirContext; 029import javax.naming.directory.InitialDirContext; 030 031import org.jivesoftware.smack.initializer.SmackAndOsgiInitializer; 032import org.jivesoftware.smack.util.DNSUtil; 033import org.jivesoftware.smack.util.dns.DNSResolver; 034import org.jivesoftware.smack.util.dns.SRVRecord; 035 036/** 037 * A DNS resolver (mostly for SRV records), which makes use of the API provided in the javax.* namespace. 038 * 039 * @author Florian Schmaus 040 * 041 */ 042public class JavaxResolver extends SmackAndOsgiInitializer implements DNSResolver { 043 044 private static JavaxResolver instance; 045 private static DirContext dirContext; 046 047 static { 048 try { 049 Hashtable<String, String> env = new Hashtable<String, String>(); 050 env.put("java.naming.factory.initial", "com.sun.jndi.dns.DnsContextFactory"); 051 dirContext = new InitialDirContext(env); 052 } catch (Exception e) { 053 // Ignore. 054 } 055 056 // Try to set this DNS resolver as primary one 057 setup(); 058 } 059 060 public JavaxResolver() { 061 062 } 063 064 public static synchronized DNSResolver getInstance() { 065 if (instance == null && isSupported()) { 066 instance = new JavaxResolver(); 067 } 068 return instance; 069 } 070 071 public static boolean isSupported() { 072 return dirContext != null; 073 } 074 075 public static void setup() { 076 DNSUtil.setDNSResolver(getInstance()); 077 } 078 079 @Override 080 public List<SRVRecord> lookupSRVRecords(String name) throws NamingException { 081 List<SRVRecord> res = new ArrayList<SRVRecord>(); 082 083 Attributes dnsLookup = dirContext.getAttributes(name, new String[] { "SRV" }); 084 Attribute srvAttribute = dnsLookup.get("SRV"); 085 if (srvAttribute == null) 086 return res; 087 @SuppressWarnings("unchecked") 088 NamingEnumeration<String> srvRecords = (NamingEnumeration<String>) srvAttribute.getAll(); 089 while (srvRecords.hasMore()) { 090 String srvRecordString = srvRecords.next(); 091 String[] srvRecordEntries = srvRecordString.split(" "); 092 int priority = Integer.parseInt(srvRecordEntries[srvRecordEntries.length - 4]); 093 int port = Integer.parseInt(srvRecordEntries[srvRecordEntries.length - 2]); 094 int weight = Integer.parseInt(srvRecordEntries[srvRecordEntries.length - 3]); 095 String host = srvRecordEntries[srvRecordEntries.length - 1]; 096 097 SRVRecord srvRecord = new SRVRecord(host, port, priority, weight); 098 res.add(srvRecord); 099 } 100 return res; 101 } 102 103 @Override 104 public List<Exception> initialize() { 105 return initialize(null); 106 } 107 108 @Override 109 public List<Exception> initialize(ClassLoader classLoader) { 110 setup(); 111 return Collections.emptyList(); 112 } 113}