Home | History | Annotate | Download | only in jmdns
      1 // /Copyright 2003-2005 Arthur van Hoff, Rick Blair
      2 // Licensed under Apache License version 2.0
      3 // Original license LGPL
      4 
      5 package javax.jmdns;
      6 
      7 import java.io.Closeable;
      8 import java.io.IOException;
      9 import java.net.InetAddress;
     10 import java.util.Collection;
     11 import java.util.Map;
     12 
     13 import javax.jmdns.impl.JmDNSImpl;
     14 
     15 /**
     16  * mDNS implementation in Java.
     17  *
     18  * @author Arthur van Hoff, Rick Blair, Jeff Sonstein, Werner Randelshofer, Pierre Frisch, Scott Lewis, Scott Cytacki
     19  */
     20 public abstract class JmDNS implements Closeable {
     21 
     22     /**
     23      *
     24      */
     25     public static interface Delegate {
     26 
     27         /**
     28          * This method is called if JmDNS cannot recover from an I/O error.
     29          *
     30          * @param dns
     31          *            target DNS
     32          * @param infos
     33          *            service info registered with the DNS
     34          */
     35         public void cannotRecoverFromIOError(JmDNS dns, Collection<ServiceInfo> infos);
     36 
     37     }
     38 
     39     /**
     40      * The version of JmDNS.
     41      */
     42     public static final String VERSION = "3.4.2";
     43 
     44     /**
     45      * <p>
     46      * Create an instance of JmDNS.
     47      * </p>
     48      * <p>
     49      * <b>Note:</b> This is a convenience method. The preferred constructor is {@link #create(InetAddress, String)}.<br/>
     50      * Check that your platform correctly handle the default localhost IP address and the local hostname. In doubt use the explicit constructor.<br/>
     51      * This call is equivalent to <code>create(null, null)</code>.
     52      * </p>
     53      *
     54      * @see #create(InetAddress, String)
     55      * @return jmDNS instance
     56      * @exception IOException
     57      *                if an exception occurs during the socket creation
     58      */
     59     public static JmDNS create() throws IOException {
     60         return new JmDNSImpl(null, null);
     61     }
     62 
     63     /**
     64      * <p>
     65      * Create an instance of JmDNS and bind it to a specific network interface given its IP-address.
     66      * </p>
     67      * <p>
     68      * <b>Note:</b> This is a convenience method. The preferred constructor is {@link #create(InetAddress, String)}.<br/>
     69      * Check that your platform correctly handle the default localhost IP address and the local hostname. In doubt use the explicit constructor.<br/>
     70      * This call is equivalent to <code>create(addr, null)</code>.
     71      * </p>
     72      *
     73      * @see #create(InetAddress, String)
     74      * @param addr
     75      *            IP address to bind to.
     76      * @return jmDNS instance
     77      * @exception IOException
     78      *                if an exception occurs during the socket creation
     79      */
     80     public static JmDNS create(final InetAddress addr) throws IOException {
     81         return new JmDNSImpl(addr, null);
     82     }
     83 
     84     /**
     85      * <p>
     86      * Create an instance of JmDNS.
     87      * </p>
     88      * <p>
     89      * <b>Note:</b> This is a convenience method. The preferred constructor is {@link #create(InetAddress, String)}.<br/>
     90      * Check that your platform correctly handle the default localhost IP address and the local hostname. In doubt use the explicit constructor.<br/>
     91      * This call is equivalent to <code>create(null, name)</code>.
     92      * </p>
     93      *
     94      * @see #create(InetAddress, String)
     95      * @param name
     96      *            name of the newly created JmDNS
     97      * @return jmDNS instance
     98      * @exception IOException
     99      *                if an exception occurs during the socket creation
    100      */
    101     public static JmDNS create(final String name) throws IOException {
    102         return new JmDNSImpl(null, name);
    103     }
    104 
    105     /**
    106      * <p>
    107      * Create an instance of JmDNS and bind it to a specific network interface given its IP-address.
    108      * </p>
    109      * If <code>addr</code> parameter is null this method will try to resolve to a local IP address of the machine using a network discovery:
    110      * <ol>
    111      * <li>Check the system property <code>net.mdns.interface</code></li>
    112      * <li>Check the JVM local host</li>
    113      * <li>Use the {@link NetworkTopologyDiscovery} to find a valid network interface and IP.</li>
    114      * <li>In the last resort bind to the loopback address. This is non functional in most cases.</li>
    115      * </ol>
    116      * If <code>name</code> parameter is null will use the hostname. The hostname is determined by the following algorithm:
    117      * <ol>
    118      * <li>Get the hostname from the InetAdress obtained before.</li>
    119      * <li>If the hostname is a reverse lookup default to <code>JmDNS name</code> or <code>computer</code> if null.</li>
    120      * <li>If the name contains <code>'.'</code> replace them by <code>'-'</code></li>
    121      * <li>Add <code>.local.</code> at the end of the name.</li>
    122      * </ol>
    123      * <p>
    124      * <b>Note:</b> If you need to use a custom {@link NetworkTopologyDiscovery} it must be setup before any call to this method. This is done by setting up a {@link NetworkTopologyDiscovery.Factory.ClassDelegate} and installing it using
    125      * {@link NetworkTopologyDiscovery.Factory#setClassDelegate(NetworkTopologyDiscovery.Factory.ClassDelegate)}. This must be done before creating a {@link JmDNS} or {@link JmmDNS} instance.
    126      * </p>
    127      *
    128      * @param addr
    129      *            IP address to bind to.
    130      * @param name
    131      *            name of the newly created JmDNS
    132      * @return jmDNS instance
    133      * @exception IOException
    134      *                if an exception occurs during the socket creation
    135      */
    136     public static JmDNS create(final InetAddress addr, final String name) throws IOException {
    137         return new JmDNSImpl(addr, name);
    138     }
    139 
    140     /**
    141      * Return the name of the JmDNS instance. This is an arbitrary string that is useful for distinguishing instances.
    142      *
    143      * @return name of the JmDNS
    144      */
    145     public abstract String getName();
    146 
    147     /**
    148      * Return the HostName associated with this JmDNS instance. Note: May not be the same as what started. The host name is subject to negotiation.
    149      *
    150      * @return Host name
    151      */
    152     public abstract String getHostName();
    153 
    154     /**
    155      * Return the address of the interface to which this instance of JmDNS is bound.
    156      *
    157      * @return Internet Address
    158      * @exception IOException
    159      *                if there is an error in the underlying protocol, such as a TCP error.
    160      */
    161     public abstract InetAddress getInetAddress() throws IOException;
    162 
    163     /**
    164      * Return the address of the interface to which this instance of JmDNS is bound.
    165      *
    166      * @return Internet Address
    167      * @exception IOException
    168      *                if there is an error in the underlying protocol, such as a TCP error.
    169      * @deprecated do not use this implementation yields unpredictable results use {@link #getInetAddress()}
    170      */
    171     @Deprecated
    172     public abstract InetAddress getInterface() throws IOException;
    173 
    174     /**
    175      * Get service information. If the information is not cached, the method will block until updated information is received.
    176      * <p/>
    177      * Usage note: Do not call this method from the AWT event dispatcher thread. You will make the user interface unresponsive.
    178      *
    179      * @param type
    180      *            fully qualified service type, such as <code>_http._tcp.local.</code> .
    181      * @param name
    182      *            unqualified service name, such as <code>foobar</code> .
    183      * @return null if the service information cannot be obtained
    184      */
    185     public abstract ServiceInfo getServiceInfo(String type, String name);
    186 
    187     /**
    188      * Get service information. If the information is not cached, the method will block for the given timeout until updated information is received.
    189      * <p/>
    190      * Usage note: If you call this method from the AWT event dispatcher thread, use a small timeout, or you will make the user interface unresponsive.
    191      *
    192      * @param type
    193      *            full qualified service type, such as <code>_http._tcp.local.</code> .
    194      * @param name
    195      *            unqualified service name, such as <code>foobar</code> .
    196      * @param timeout
    197      *            timeout in milliseconds. Typical timeout should be 5s.
    198      * @return null if the service information cannot be obtained
    199      */
    200     public abstract ServiceInfo getServiceInfo(String type, String name, long timeout);
    201 
    202     /**
    203      * Get service information. If the information is not cached, the method will block until updated information is received.
    204      * <p/>
    205      * Usage note: Do not call this method from the AWT event dispatcher thread. You will make the user interface unresponsive.
    206      *
    207      * @param type
    208      *            fully qualified service type, such as <code>_http._tcp.local.</code> .
    209      * @param name
    210      *            unqualified service name, such as <code>foobar</code> .
    211      * @param persistent
    212      *            if <code>true</code> ServiceListener.resolveService will be called whenever new new information is received.
    213      * @return null if the service information cannot be obtained
    214      */
    215     public abstract ServiceInfo getServiceInfo(String type, String name, boolean persistent);
    216 
    217     /**
    218      * Get service information. If the information is not cached, the method will block for the given timeout until updated information is received.
    219      * <p/>
    220      * Usage note: If you call this method from the AWT event dispatcher thread, use a small timeout, or you will make the user interface unresponsive.
    221      *
    222      * @param type
    223      *            full qualified service type, such as <code>_http._tcp.local.</code> .
    224      * @param name
    225      *            unqualified service name, such as <code>foobar</code> .
    226      * @param timeout
    227      *            timeout in milliseconds. Typical timeout should be 5s.
    228      * @param persistent
    229      *            if <code>true</code> ServiceListener.resolveService will be called whenever new new information is received.
    230      * @return null if the service information cannot be obtained
    231      */
    232     public abstract ServiceInfo getServiceInfo(String type, String name, boolean persistent, long timeout);
    233 
    234     /**
    235      * Request service information. The information about the service is requested and the ServiceListener.resolveService method is called as soon as it is available.
    236      * <p/>
    237      * Usage note: Do not call this method from the AWT event dispatcher thread. You will make the user interface unresponsive.
    238      *
    239      * @param type
    240      *            full qualified service type, such as <code>_http._tcp.local.</code> .
    241      * @param name
    242      *            unqualified service name, such as <code>foobar</code> .
    243      */
    244     public abstract void requestServiceInfo(String type, String name);
    245 
    246     /**
    247      * Request service information. The information about the service is requested and the ServiceListener.resolveService method is called as soon as it is available.
    248      * <p/>
    249      * Usage note: Do not call this method from the AWT event dispatcher thread. You will make the user interface unresponsive.
    250      *
    251      * @param type
    252      *            full qualified service type, such as <code>_http._tcp.local.</code> .
    253      * @param name
    254      *            unqualified service name, such as <code>foobar</code> .
    255      * @param persistent
    256      *            if <code>true</code> ServiceListener.resolveService will be called whenever new new information is received.
    257      */
    258     public abstract void requestServiceInfo(String type, String name, boolean persistent);
    259 
    260     /**
    261      * Request service information. The information about the service is requested and the ServiceListener.resolveService method is called as soon as it is available.
    262      *
    263      * @param type
    264      *            full qualified service type, such as <code>_http._tcp.local.</code> .
    265      * @param name
    266      *            unqualified service name, such as <code>foobar</code> .
    267      * @param timeout
    268      *            timeout in milliseconds
    269      */
    270     public abstract void requestServiceInfo(String type, String name, long timeout);
    271 
    272     /**
    273      * Request service information. The information about the service is requested and the ServiceListener.resolveService method is called as soon as it is available.
    274      *
    275      * @param type
    276      *            full qualified service type, such as <code>_http._tcp.local.</code> .
    277      * @param name
    278      *            unqualified service name, such as <code>foobar</code> .
    279      * @param persistent
    280      *            if <code>true</code> ServiceListener.resolveService will be called whenever new new information is received.
    281      * @param timeout
    282      *            timeout in milliseconds
    283      */
    284     public abstract void requestServiceInfo(String type, String name, boolean persistent, long timeout);
    285 
    286     /**
    287      * Listen for service types.
    288      *
    289      * @param listener
    290      *            listener for service types
    291      * @exception IOException
    292      *                if there is an error in the underlying protocol, such as a TCP error.
    293      */
    294     public abstract void addServiceTypeListener(ServiceTypeListener listener) throws IOException;
    295 
    296     /**
    297      * Remove listener for service types.
    298      *
    299      * @param listener
    300      *            listener for service types
    301      */
    302     public abstract void removeServiceTypeListener(ServiceTypeListener listener);
    303 
    304     /**
    305      * Listen for services of a given type. The type has to be a fully qualified type name such as <code>_http._tcp.local.</code>.
    306      *
    307      * @param type
    308      *            full qualified service type, such as <code>_http._tcp.local.</code>.
    309      * @param listener
    310      *            listener for service updates
    311      */
    312     public abstract void addServiceListener(String type, ServiceListener listener);
    313 
    314     /**
    315      * Remove listener for services of a given type.
    316      *
    317      * @param type
    318      *            full qualified service type, such as <code>_http._tcp.local.</code>.
    319      * @param listener
    320      *            listener for service updates
    321      */
    322     public abstract void removeServiceListener(String type, ServiceListener listener);
    323 
    324     /**
    325      * Register a service. The service is registered for access by other jmdns clients. The name of the service may be changed to make it unique.<br>
    326      * Note that the given {@code ServiceInfo} is bound to this {@code JmDNS} instance, and should not be reused for any other {@linkplain #registerService(ServiceInfo)}.
    327      *
    328      * @param info
    329      *            service info to register
    330      * @exception IOException
    331      *                if there is an error in the underlying protocol, such as a TCP error.
    332      */
    333     public abstract void registerService(ServiceInfo info) throws IOException;
    334 
    335     /**
    336      * Unregister a service. The service should have been registered.
    337      * <p>
    338      * <b>Note:</b> Unregistered services will not disappear form the list of services immediately. According to the specification, when unregistering services we send goodbye packets and then wait <b>1s</b> before purging the cache.<br/>
    339      * This is support for shared records that can be rescued by some other cooperation DNS.
    340      *
    341      * <pre>
    342      * Clients receiving a Multicast DNS Response with a TTL of zero SHOULD NOT immediately delete the record from the cache, but instead record a TTL of 1 and then delete the record one second later.
    343      * </pre>
    344      *
    345      * </p>
    346      *
    347      * @param info
    348      *            service info to remove
    349      */
    350     public abstract void unregisterService(ServiceInfo info);
    351 
    352     /**
    353      * Unregister all services.
    354      */
    355     public abstract void unregisterAllServices();
    356 
    357     /**
    358      * Register a service type. If this service type was not already known, all service listeners will be notified of the new service type.
    359      * <p>
    360      * Service types are automatically registered as they are discovered.
    361      * </p>
    362      *
    363      * @param type
    364      *            full qualified service type, such as <code>_http._tcp.local.</code>.
    365      * @return <code>true</code> if the type or subtype was added, <code>false</code> if the type was already registered.
    366      */
    367     public abstract boolean registerServiceType(String type);
    368 
    369     /**
    370      * List Services and serviceTypes. Debugging Only
    371      *
    372      * @deprecated since 3.2.2
    373      */
    374     @Deprecated
    375     public abstract void printServices();
    376 
    377     /**
    378      * Returns a list of service infos of the specified type.
    379      *
    380      * @param type
    381      *            Service type name, such as <code>_http._tcp.local.</code>.
    382      * @return An array of service instance.
    383      */
    384     public abstract ServiceInfo[] list(String type);
    385 
    386     /**
    387      * Returns a list of service infos of the specified type.
    388      *
    389      * @param type
    390      *            Service type name, such as <code>_http._tcp.local.</code>.
    391      * @param timeout
    392      *            timeout in milliseconds. Typical timeout should be 6s.
    393      * @return An array of service instance.
    394      */
    395     public abstract ServiceInfo[] list(String type, long timeout);
    396 
    397     /**
    398      * Returns a list of service infos of the specified type sorted by subtype. Any service that do not register a subtype is listed in the empty subtype section.
    399      *
    400      * @param type
    401      *            Service type name, such as <code>_http._tcp.local.</code>.
    402      * @return A dictionary of service info by subtypes.
    403      */
    404     public abstract Map<String, ServiceInfo[]> listBySubtype(String type);
    405 
    406     /**
    407      * Returns a list of service infos of the specified type sorted by subtype. Any service that do not register a subtype is listed in the empty subtype section.
    408      *
    409      * @param type
    410      *            Service type name, such as <code>_http._tcp.local.</code>.
    411      * @param timeout
    412      *            timeout in milliseconds. Typical timeout should be 6s.
    413      * @return A dictionary of service info by subtypes.
    414      */
    415     public abstract Map<String, ServiceInfo[]> listBySubtype(String type, long timeout);
    416 
    417     /**
    418      * Returns the instance delegate
    419      *
    420      * @return instance delegate
    421      */
    422     public abstract Delegate getDelegate();
    423 
    424     /**
    425      * Sets the instance delegate
    426      *
    427      * @param value
    428      *            new instance delegate
    429      * @return previous instance delegate
    430      */
    431     public abstract Delegate setDelegate(Delegate value);
    432 
    433 }
    434