13742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman/** 23742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman * 33742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman */ 43742d9db8b6edb10627b0f89336cca5249f1d15aManuel Romanpackage javax.jmdns.impl; 53742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman 63742d9db8b6edb10627b0f89336cca5249f1d15aManuel Romanimport java.io.IOException; 73742d9db8b6edb10627b0f89336cca5249f1d15aManuel Romanimport java.net.InetAddress; 83742d9db8b6edb10627b0f89336cca5249f1d15aManuel Romanimport java.util.ArrayList; 93742d9db8b6edb10627b0f89336cca5249f1d15aManuel Romanimport java.util.Arrays; 103742d9db8b6edb10627b0f89336cca5249f1d15aManuel Romanimport java.util.Collections; 113742d9db8b6edb10627b0f89336cca5249f1d15aManuel Romanimport java.util.HashMap; 123742d9db8b6edb10627b0f89336cca5249f1d15aManuel Romanimport java.util.HashSet; 133742d9db8b6edb10627b0f89336cca5249f1d15aManuel Romanimport java.util.List; 143742d9db8b6edb10627b0f89336cca5249f1d15aManuel Romanimport java.util.Map; 153742d9db8b6edb10627b0f89336cca5249f1d15aManuel Romanimport java.util.Set; 163742d9db8b6edb10627b0f89336cca5249f1d15aManuel Romanimport java.util.Timer; 173742d9db8b6edb10627b0f89336cca5249f1d15aManuel Romanimport java.util.TimerTask; 183742d9db8b6edb10627b0f89336cca5249f1d15aManuel Romanimport java.util.concurrent.ConcurrentHashMap; 193742d9db8b6edb10627b0f89336cca5249f1d15aManuel Romanimport java.util.concurrent.ConcurrentMap; 203742d9db8b6edb10627b0f89336cca5249f1d15aManuel Romanimport java.util.concurrent.ExecutorService; 213742d9db8b6edb10627b0f89336cca5249f1d15aManuel Romanimport java.util.concurrent.Executors; 223742d9db8b6edb10627b0f89336cca5249f1d15aManuel Romanimport java.util.concurrent.TimeUnit; 233742d9db8b6edb10627b0f89336cca5249f1d15aManuel Romanimport java.util.logging.Level; 243742d9db8b6edb10627b0f89336cca5249f1d15aManuel Romanimport java.util.logging.Logger; 253742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman 263742d9db8b6edb10627b0f89336cca5249f1d15aManuel Romanimport javax.jmdns.JmDNS; 273742d9db8b6edb10627b0f89336cca5249f1d15aManuel Romanimport javax.jmdns.JmmDNS; 283742d9db8b6edb10627b0f89336cca5249f1d15aManuel Romanimport javax.jmdns.NetworkTopologyDiscovery; 293742d9db8b6edb10627b0f89336cca5249f1d15aManuel Romanimport javax.jmdns.NetworkTopologyEvent; 303742d9db8b6edb10627b0f89336cca5249f1d15aManuel Romanimport javax.jmdns.NetworkTopologyListener; 313742d9db8b6edb10627b0f89336cca5249f1d15aManuel Romanimport javax.jmdns.ServiceInfo; 323742d9db8b6edb10627b0f89336cca5249f1d15aManuel Romanimport javax.jmdns.ServiceListener; 333742d9db8b6edb10627b0f89336cca5249f1d15aManuel Romanimport javax.jmdns.ServiceTypeListener; 343742d9db8b6edb10627b0f89336cca5249f1d15aManuel Romanimport javax.jmdns.impl.constants.DNSConstants; 353742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman 363742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman/** 373742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman * This class enable multihomming mDNS. It will open a mDNS per IP address of the machine. 383742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman * 393742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman * @author Cédrik Lime, Pierre Frisch 403742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman */ 413742d9db8b6edb10627b0f89336cca5249f1d15aManuel Romanpublic class JmmDNSImpl implements JmmDNS, NetworkTopologyListener, ServiceInfoImpl.Delegate { 423742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman private static Logger logger = Logger.getLogger(JmmDNSImpl.class.getName()); 433742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman 443742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman private final Set<NetworkTopologyListener> _networkListeners; 453742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman 463742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman /** 473742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman * Every JmDNS created. 483742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman */ 493742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman private final ConcurrentMap<InetAddress, JmDNS> _knownMDNS; 503742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman 513742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman /** 523742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman * This enable the service info text update. 533742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman */ 543742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman private final ConcurrentMap<String, ServiceInfo> _services; 553742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman 563742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman private final ExecutorService _ListenerExecutor; 573742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman 583742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman private final ExecutorService _jmDNSExecutor; 593742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman 603742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman private final Timer _timer; 613742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman 623742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman /** 633742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman * 643742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman */ 653742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman public JmmDNSImpl() { 663742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman super(); 673742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman _networkListeners = Collections.synchronizedSet(new HashSet<NetworkTopologyListener>()); 683742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman _knownMDNS = new ConcurrentHashMap<InetAddress, JmDNS>(); 693742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman _services = new ConcurrentHashMap<String, ServiceInfo>(20); 703742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman _ListenerExecutor = Executors.newSingleThreadExecutor(); 713742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman _jmDNSExecutor = Executors.newCachedThreadPool(); 723742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman _timer = new Timer("Multihommed mDNS.Timer", true); 733742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman (new NetworkChecker(this, NetworkTopologyDiscovery.Factory.getInstance())).start(_timer); 743742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } 753742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman 763742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman /* 773742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman * (non-Javadoc) 783742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman * @see java.io.Closeable#close() 793742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman */ 803742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman @Override 813742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman public void close() throws IOException { 823742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman if (logger.isLoggable(Level.FINER)) { 833742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman logger.finer("Cancelling JmmDNS: " + this); 843742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } 853742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman _timer.cancel(); 863742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman _ListenerExecutor.shutdown(); 873742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman // We need to cancel all the DNS 883742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman ExecutorService executor = Executors.newCachedThreadPool(); 893742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman for (final JmDNS mDNS : _knownMDNS.values()) { 903742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman executor.submit(new Runnable() { 913742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman /** 923742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman * {@inheritDoc} 933742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman */ 943742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman @Override 953742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman public void run() { 963742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman try { 973742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman mDNS.close(); 983742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } catch (IOException exception) { 993742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman // JmDNS never throws this is only because of the closeable interface 1003742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } 1013742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } 1023742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman }); 1033742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } 1043742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman executor.shutdown(); 1053742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman try { 1063742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman executor.awaitTermination(DNSConstants.CLOSE_TIMEOUT, TimeUnit.MILLISECONDS); 1073742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } catch (InterruptedException exception) { 1083742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman logger.log(Level.WARNING, "Exception ", exception); 1093742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } 1103742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman _knownMDNS.clear(); 1113742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } 1123742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman 1133742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman /* 1143742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman * (non-Javadoc) 1153742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman * @see javax.jmdns.JmmDNS#getNames() 1163742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman */ 1173742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman @Override 1183742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman public String[] getNames() { 1193742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman Set<String> result = new HashSet<String>(); 1203742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman for (JmDNS mDNS : _knownMDNS.values()) { 1213742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman result.add(mDNS.getName()); 1223742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } 1233742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman return result.toArray(new String[result.size()]); 1243742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } 1253742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman 1263742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman /* 1273742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman * (non-Javadoc) 1283742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman * @see javax.jmdns.JmmDNS#getHostNames() 1293742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman */ 1303742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman @Override 1313742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman public String[] getHostNames() { 1323742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman Set<String> result = new HashSet<String>(); 1333742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman for (JmDNS mDNS : _knownMDNS.values()) { 1343742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman result.add(mDNS.getHostName()); 1353742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } 1363742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman return result.toArray(new String[result.size()]); 1373742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } 1383742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman 1393742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman /* 1403742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman * (non-Javadoc) 1413742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman * @see javax.jmdns.JmmDNS#getInetAddresses() 1423742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman */ 1433742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman @Override 1443742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman public InetAddress[] getInetAddresses() throws IOException { 1453742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman Set<InetAddress> result = new HashSet<InetAddress>(); 1463742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman for (JmDNS mDNS : _knownMDNS.values()) { 1473742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman result.add(mDNS.getInetAddress()); 1483742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } 1493742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman return result.toArray(new InetAddress[result.size()]); 1503742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } 1513742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman 1523742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman /* 1533742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman * (non-Javadoc) 1543742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman * @see javax.jmdns.JmmDNS#getInterfaces() 1553742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman */ 1563742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman @Override 1573742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman @Deprecated 1583742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman public InetAddress[] getInterfaces() throws IOException { 1593742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman Set<InetAddress> result = new HashSet<InetAddress>(); 1603742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman for (JmDNS mDNS : _knownMDNS.values()) { 1613742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman result.add(mDNS.getInterface()); 1623742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } 1633742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman return result.toArray(new InetAddress[result.size()]); 1643742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } 1653742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman 1663742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman /* 1673742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman * (non-Javadoc) 1683742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman * @see javax.jmdns.JmmDNS#getServiceInfos(java.lang.String, java.lang.String) 1693742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman */ 1703742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman @Override 1713742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman public ServiceInfo[] getServiceInfos(String type, String name) { 1723742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman return this.getServiceInfos(type, name, false, DNSConstants.SERVICE_INFO_TIMEOUT); 1733742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } 1743742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman 1753742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman /* 1763742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman * (non-Javadoc) 1773742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman * @see javax.jmdns.JmmDNS#getServiceInfos(java.lang.String, java.lang.String, long) 1783742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman */ 1793742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman @Override 1803742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman public ServiceInfo[] getServiceInfos(String type, String name, long timeout) { 1813742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman return this.getServiceInfos(type, name, false, timeout); 1823742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } 1833742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman 1843742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman /* 1853742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman * (non-Javadoc) 1863742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman * @see javax.jmdns.JmmDNS#getServiceInfos(java.lang.String, java.lang.String, boolean) 1873742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman */ 1883742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman @Override 1893742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman public ServiceInfo[] getServiceInfos(String type, String name, boolean persistent) { 1903742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman return this.getServiceInfos(type, name, persistent, DNSConstants.SERVICE_INFO_TIMEOUT); 1913742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } 1923742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman 1933742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman /* 1943742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman * (non-Javadoc) 1953742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman * @see javax.jmdns.JmmDNS#getServiceInfos(java.lang.String, java.lang.String, boolean, long) 1963742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman */ 1973742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman @Override 1983742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman public ServiceInfo[] getServiceInfos(final String type, final String name, final boolean persistent, final long timeout) { 1993742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman // We need to run this in parallel to respect the timeout. 2003742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman final Set<ServiceInfo> result = Collections.synchronizedSet(new HashSet<ServiceInfo>(_knownMDNS.size())); 2013742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman ExecutorService executor = Executors.newCachedThreadPool(); 2023742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman for (final JmDNS mDNS : _knownMDNS.values()) { 2033742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman executor.submit(new Runnable() { 2043742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman /** 2053742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman * {@inheritDoc} 2063742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman */ 2073742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman @Override 2083742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman public void run() { 2093742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman result.add(mDNS.getServiceInfo(type, name, persistent, timeout)); 2103742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } 2113742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman }); 2123742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } 2133742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman executor.shutdown(); 2143742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman try { 2153742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman executor.awaitTermination(timeout, TimeUnit.MILLISECONDS); 2163742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } catch (InterruptedException exception) { 2173742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman logger.log(Level.WARNING, "Exception ", exception); 2183742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } 2193742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman return result.toArray(new ServiceInfo[result.size()]); 2203742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } 2213742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman 2223742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman /* 2233742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman * (non-Javadoc) 2243742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman * @see javax.jmdns.JmmDNS#requestServiceInfo(java.lang.String, java.lang.String) 2253742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman */ 2263742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman @Override 2273742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman public void requestServiceInfo(String type, String name) { 2283742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman this.requestServiceInfo(type, name, false, DNSConstants.SERVICE_INFO_TIMEOUT); 2293742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } 2303742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman 2313742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman /* 2323742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman * (non-Javadoc) 2333742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman * @see javax.jmdns.JmmDNS#requestServiceInfo(java.lang.String, java.lang.String, boolean) 2343742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman */ 2353742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman @Override 2363742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman public void requestServiceInfo(String type, String name, boolean persistent) { 2373742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman this.requestServiceInfo(type, name, persistent, DNSConstants.SERVICE_INFO_TIMEOUT); 2383742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } 2393742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman 2403742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman /* 2413742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman * (non-Javadoc) 2423742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman * @see javax.jmdns.JmmDNS#requestServiceInfo(java.lang.String, java.lang.String, long) 2433742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman */ 2443742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman @Override 2453742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman public void requestServiceInfo(String type, String name, long timeout) { 2463742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman this.requestServiceInfo(type, name, false, timeout); 2473742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } 2483742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman 2493742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman /* 2503742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman * (non-Javadoc) 2513742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman * @see javax.jmdns.JmmDNS#requestServiceInfo(java.lang.String, java.lang.String, boolean, long) 2523742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman */ 2533742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman @Override 2543742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman public void requestServiceInfo(final String type, final String name, final boolean persistent, final long timeout) { 2553742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman // We need to run this in parallel to respect the timeout. 2563742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman for (final JmDNS mDNS : _knownMDNS.values()) { 2573742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman _jmDNSExecutor.submit(new Runnable() { 2583742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman /** 2593742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman * {@inheritDoc} 2603742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman */ 2613742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman @Override 2623742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman public void run() { 2633742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman mDNS.requestServiceInfo(type, name, persistent, timeout); 2643742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } 2653742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman }); 2663742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } 2673742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } 2683742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman 2693742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman /* 2703742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman * (non-Javadoc) 2713742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman * @see javax.jmdns.JmmDNS#addServiceTypeListener(javax.jmdns.ServiceTypeListener) 2723742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman */ 2733742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman @Override 2743742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman public void addServiceTypeListener(ServiceTypeListener listener) throws IOException { 2753742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman for (JmDNS mDNS : _knownMDNS.values()) { 2763742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman mDNS.addServiceTypeListener(listener); 2773742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } 2783742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } 2793742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman 2803742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman /* 2813742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman * (non-Javadoc) 2823742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman * @see javax.jmdns.JmmDNS#removeServiceTypeListener(javax.jmdns.ServiceTypeListener) 2833742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman */ 2843742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman @Override 2853742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman public void removeServiceTypeListener(ServiceTypeListener listener) { 2863742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman for (JmDNS mDNS : _knownMDNS.values()) { 2873742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman mDNS.removeServiceTypeListener(listener); 2883742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } 2893742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } 2903742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman 2913742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman /* 2923742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman * (non-Javadoc) 2933742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman * @see javax.jmdns.JmmDNS#addServiceListener(java.lang.String, javax.jmdns.ServiceListener) 2943742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman */ 2953742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman @Override 2963742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman public void addServiceListener(String type, ServiceListener listener) { 2973742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman for (JmDNS mDNS : _knownMDNS.values()) { 2983742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman mDNS.addServiceListener(type, listener); 2993742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } 3003742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } 3013742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman 3023742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman /* 3033742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman * (non-Javadoc) 3043742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman * @see javax.jmdns.JmmDNS#removeServiceListener(java.lang.String, javax.jmdns.ServiceListener) 3053742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman */ 3063742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman @Override 3073742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman public void removeServiceListener(String type, ServiceListener listener) { 3083742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman for (JmDNS mDNS : _knownMDNS.values()) { 3093742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman mDNS.removeServiceListener(type, listener); 3103742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } 3113742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } 3123742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman 3133742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman /* 3143742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman * (non-Javadoc) 3153742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman * @see javax.jmdns.impl.ServiceInfoImpl.Delegate#textValueUpdated(javax.jmdns.ServiceInfo, byte[]) 3163742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman */ 3173742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman @Override 3183742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman public void textValueUpdated(ServiceInfo target, byte[] value) { 3193742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman synchronized (_services) { 3203742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman for (JmDNS mDNS : _knownMDNS.values()) { 3213742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman ServiceInfo info = ((JmDNSImpl) mDNS).getServices().get(target.getQualifiedName()); 3223742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman if (info != null) { 3233742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman info.setText(value); 3243742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } else { 3253742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman logger.warning("We have a mDNS that does not know about the service info being updated."); 3263742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } 3273742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } 3283742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } 3293742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } 3303742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman 3313742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman /* 3323742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman * (non-Javadoc) 3333742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman * @see javax.jmdns.JmmDNS#registerService(javax.jmdns.ServiceInfo) 3343742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman */ 3353742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman @Override 3363742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman public void registerService(ServiceInfo info) throws IOException { 3373742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman // This is really complex. We need to clone the service info for each DNS but then we loose the ability to update it. 3383742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman synchronized (_services) { 3393742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman for (JmDNS mDNS : _knownMDNS.values()) { 3403742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman mDNS.registerService(info.clone()); 3413742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } 3423742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman ((ServiceInfoImpl) info).setDelegate(this); 3433742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman _services.put(info.getQualifiedName(), info); 3443742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } 3453742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } 3463742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman 3473742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman /* 3483742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman * (non-Javadoc) 3493742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman * @see javax.jmdns.JmmDNS#unregisterService(javax.jmdns.ServiceInfo) 3503742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman */ 3513742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman @Override 3523742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman public void unregisterService(ServiceInfo info) { 3533742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman synchronized (_services) { 3543742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman for (JmDNS mDNS : _knownMDNS.values()) { 3553742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman mDNS.unregisterService(info); 3563742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } 3573742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman ((ServiceInfoImpl) info).setDelegate(null); 3583742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman _services.remove(info.getQualifiedName()); 3593742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } 3603742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } 3613742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman 3623742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman /* 3633742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman * (non-Javadoc) 3643742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman * @see javax.jmdns.JmmDNS#unregisterAllServices() 3653742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman */ 3663742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman @Override 3673742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman public void unregisterAllServices() { 3683742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman synchronized (_services) { 3693742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman for (JmDNS mDNS : _knownMDNS.values()) { 3703742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman mDNS.unregisterAllServices(); 3713742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } 3723742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman _services.clear(); 3733742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } 3743742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } 3753742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman 3763742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman /* 3773742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman * (non-Javadoc) 3783742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman * @see javax.jmdns.JmmDNS#registerServiceType(java.lang.String) 3793742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman */ 3803742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman @Override 3813742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman public void registerServiceType(String type) { 3823742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman for (JmDNS mDNS : _knownMDNS.values()) { 3833742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman mDNS.registerServiceType(type); 3843742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } 3853742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } 3863742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman 3873742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman /* 3883742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman * (non-Javadoc) 3893742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman * @see javax.jmdns.JmmDNS#list(java.lang.String) 3903742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman */ 3913742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman @Override 3923742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman public ServiceInfo[] list(String type) { 3933742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman return this.list(type, DNSConstants.SERVICE_INFO_TIMEOUT); 3943742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } 3953742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman 3963742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman /* 3973742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman * (non-Javadoc) 3983742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman * @see javax.jmdns.JmmDNS#list(java.lang.String, long) 3993742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman */ 4003742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman @Override 4013742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman public ServiceInfo[] list(final String type, final long timeout) { 4023742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman // We need to run this in parallel to respect the timeout. 4033742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman final Set<ServiceInfo> result = Collections.synchronizedSet(new HashSet<ServiceInfo>(_knownMDNS.size() * 5)); 4043742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman ExecutorService executor = Executors.newCachedThreadPool(); 4053742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman for (final JmDNS mDNS : _knownMDNS.values()) { 4063742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman executor.submit(new Runnable() { 4073742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman /** 4083742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman * {@inheritDoc} 4093742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman */ 4103742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman @Override 4113742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman public void run() { 4123742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman result.addAll(Arrays.asList(mDNS.list(type, timeout))); 4133742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } 4143742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman }); 4153742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } 4163742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman executor.shutdown(); 4173742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman try { 4183742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman executor.awaitTermination(timeout, TimeUnit.MILLISECONDS); 4193742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } catch (InterruptedException exception) { 4203742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman logger.log(Level.WARNING, "Exception ", exception); 4213742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } 4223742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman return result.toArray(new ServiceInfo[result.size()]); 4233742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } 4243742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman 4253742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman /* 4263742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman * (non-Javadoc) 4273742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman * @see javax.jmdns.JmmDNS#listBySubtype(java.lang.String) 4283742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman */ 4293742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman @Override 4303742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman public Map<String, ServiceInfo[]> listBySubtype(String type) { 4313742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman return this.listBySubtype(type, DNSConstants.SERVICE_INFO_TIMEOUT); 4323742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } 4333742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman 4343742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman /* 4353742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman * (non-Javadoc) 4363742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman * @see javax.jmdns.JmmDNS#listBySubtype(java.lang.String, long) 4373742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman */ 4383742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman @Override 4393742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman public Map<String, ServiceInfo[]> listBySubtype(final String type, final long timeout) { 4403742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman Map<String, List<ServiceInfo>> map = new HashMap<String, List<ServiceInfo>>(5); 4413742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman for (ServiceInfo info : this.list(type, timeout)) { 4423742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman String subtype = info.getSubtype(); 4433742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman if (!map.containsKey(subtype)) { 4443742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman map.put(subtype, new ArrayList<ServiceInfo>(10)); 4453742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } 4463742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman map.get(subtype).add(info); 4473742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } 4483742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman 4493742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman Map<String, ServiceInfo[]> result = new HashMap<String, ServiceInfo[]>(map.size()); 4503742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman for (String subtype : map.keySet()) { 4513742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman List<ServiceInfo> infoForSubType = map.get(subtype); 4523742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman result.put(subtype, infoForSubType.toArray(new ServiceInfo[infoForSubType.size()])); 4533742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } 4543742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman 4553742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman return result; 4563742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } 4573742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman 4583742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman /* 4593742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman * (non-Javadoc) 4603742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman * @see javax.jmdns.JmmDNS#addNetworkTopologyListener(javax.jmdns.NetworkTopologyListener) 4613742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman */ 4623742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman @Override 4633742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman public void addNetworkTopologyListener(NetworkTopologyListener listener) { 4643742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman _networkListeners.add(listener); 4653742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } 4663742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman 4673742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman /* 4683742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman * (non-Javadoc) 4693742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman * @see javax.jmdns.JmmDNS#removeNetworkTopologyListener(javax.jmdns.NetworkTopologyListener) 4703742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman */ 4713742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman @Override 4723742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman public void removeNetworkTopologyListener(NetworkTopologyListener listener) { 4733742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman _networkListeners.remove(listener); 4743742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } 4753742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman 4763742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman /* 4773742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman * (non-Javadoc) 4783742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman * @see javax.jmdns.JmmDNS#networkListeners() 4793742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman */ 4803742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman @Override 4813742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman public NetworkTopologyListener[] networkListeners() { 4823742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman return _networkListeners.toArray(new NetworkTopologyListener[_networkListeners.size()]); 4833742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } 4843742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman 4853742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman /* 4863742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman * (non-Javadoc) 4873742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman * @see javax.jmdns.NetworkTopologyListener#inetAddressAdded(javax.jmdns.NetworkTopologyEvent) 4883742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman */ 4893742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman @Override 4903742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman public void inetAddressAdded(NetworkTopologyEvent event) { 4913742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman InetAddress address = event.getInetAddress(); 4923742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman try { 4933742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman synchronized (this) { 4943742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman if (!_knownMDNS.containsKey(address)) { 4953742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman _knownMDNS.put(address, JmDNS.create(address)); 4963742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman final NetworkTopologyEvent jmdnsEvent = new NetworkTopologyEventImpl(_knownMDNS.get(address), address); 4973742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman for (final NetworkTopologyListener listener : this.networkListeners()) { 4983742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman _ListenerExecutor.submit(new Runnable() { 4993742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman /** 5003742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman * {@inheritDoc} 5013742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman */ 5023742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman @Override 5033742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman public void run() { 5043742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman listener.inetAddressAdded(jmdnsEvent); 5053742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } 5063742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman }); 5073742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } 5083742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } 5093742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } 5103742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } catch (Exception e) { 5113742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman logger.warning("Unexpected unhandled exception: " + e); 5123742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } 5133742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } 5143742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman 5153742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman /* 5163742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman * (non-Javadoc) 5173742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman * @see javax.jmdns.NetworkTopologyListener#inetAddressRemoved(javax.jmdns.NetworkTopologyEvent) 5183742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman */ 5193742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman @Override 5203742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman public void inetAddressRemoved(NetworkTopologyEvent event) { 5213742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman InetAddress address = event.getInetAddress(); 5223742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman try { 5233742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman synchronized (this) { 5243742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman if (_knownMDNS.containsKey(address)) { 5253742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman JmDNS mDNS = _knownMDNS.remove(address); 5263742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman mDNS.close(); 5273742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman final NetworkTopologyEvent jmdnsEvent = new NetworkTopologyEventImpl(mDNS, address); 5283742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman for (final NetworkTopologyListener listener : this.networkListeners()) { 5293742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman _ListenerExecutor.submit(new Runnable() { 5303742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman /** 5313742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman * {@inheritDoc} 5323742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman */ 5333742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman @Override 5343742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman public void run() { 5353742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman listener.inetAddressRemoved(jmdnsEvent); 5363742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } 5373742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman }); 5383742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } 5393742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } 5403742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } 5413742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } catch (Exception e) { 5423742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman logger.warning("Unexpected unhandled exception: " + e); 5433742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } 5443742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } 5453742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman 5463742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman /** 5473742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman * Checks the network state.<br/> 5483742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman * If the network change, this class will reconfigure the list of DNS do adapt to the new configuration. 5493742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman */ 5503742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman static class NetworkChecker extends TimerTask { 5513742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman private static Logger logger1 = Logger.getLogger(NetworkChecker.class.getName()); 5523742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman 5533742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman private final NetworkTopologyListener _mmDNS; 5543742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman 5553742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman private final NetworkTopologyDiscovery _topology; 5563742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman 5573742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman private Set<InetAddress> _knownAddresses; 5583742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman 5593742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman public NetworkChecker(NetworkTopologyListener mmDNS, NetworkTopologyDiscovery topology) { 5603742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman super(); 5613742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman this._mmDNS = mmDNS; 5623742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman this._topology = topology; 5633742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman _knownAddresses = Collections.synchronizedSet(new HashSet<InetAddress>()); 5643742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } 5653742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman 5663742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman public void start(Timer timer) { 5673742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman timer.schedule(this, 0, DNSConstants.NETWORK_CHECK_INTERVAL); 5683742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } 5693742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman 5703742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman /** 5713742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman * {@inheritDoc} 5723742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman */ 5733742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman @Override 5743742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman public void run() { 5753742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman try { 5763742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman InetAddress[] curentAddresses = _topology.getInetAddresses(); 5773742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman Set<InetAddress> current = new HashSet<InetAddress>(curentAddresses.length); 5783742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman for (InetAddress address : curentAddresses) { 5793742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman current.add(address); 5803742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman if (!_knownAddresses.contains(address)) { 5813742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman final NetworkTopologyEvent event = new NetworkTopologyEventImpl(_mmDNS, address); 5823742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman _mmDNS.inetAddressAdded(event); 5833742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } 5843742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } 5853742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman for (InetAddress address : _knownAddresses) { 5863742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman if (!current.contains(address)) { 5873742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman final NetworkTopologyEvent event = new NetworkTopologyEventImpl(_mmDNS, address); 5883742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman _mmDNS.inetAddressRemoved(event); 5893742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } 5903742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } 5913742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman _knownAddresses = current; 5923742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } catch (Exception e) { 5933742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman logger1.warning("Unexpected unhandled exception: " + e); 5943742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } 5953742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } 5963742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman 5973742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } 5983742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman 5993742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman} 600