View Javadoc

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.1";
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 getInterface() throws IOException;
162 
163     /**
164      * Get service information. If the information is not cached, the method will block until updated information is received.
165      * <p/>
166      * Usage note: Do not call this method from the AWT event dispatcher thread. You will make the user interface unresponsive.
167      *
168      * @param type
169      *            fully qualified service type, such as <code>_http._tcp.local.</code> .
170      * @param name
171      *            unqualified service name, such as <code>foobar</code> .
172      * @return null if the service information cannot be obtained
173      */
174     public abstract ServiceInfo getServiceInfo(String type, String name);
175 
176     /**
177      * Get service information. If the information is not cached, the method will block for the given timeout until updated information is received.
178      * <p/>
179      * 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.
180      *
181      * @param type
182      *            full qualified service type, such as <code>_http._tcp.local.</code> .
183      * @param name
184      *            unqualified service name, such as <code>foobar</code> .
185      * @param timeout
186      *            timeout in milliseconds. Typical timeout should be 5s.
187      * @return null if the service information cannot be obtained
188      */
189     public abstract ServiceInfo getServiceInfo(String type, String name, long timeout);
190 
191     /**
192      * Get service information. If the information is not cached, the method will block until updated information is received.
193      * <p/>
194      * Usage note: Do not call this method from the AWT event dispatcher thread. You will make the user interface unresponsive.
195      *
196      * @param type
197      *            fully qualified service type, such as <code>_http._tcp.local.</code> .
198      * @param name
199      *            unqualified service name, such as <code>foobar</code> .
200      * @param persistent
201      *            if <code>true</code> ServiceListener.resolveService will be called whenever new new information is received.
202      * @return null if the service information cannot be obtained
203      */
204     public abstract ServiceInfo getServiceInfo(String type, String name, boolean persistent);
205 
206     /**
207      * Get service information. If the information is not cached, the method will block for the given timeout until updated information is received.
208      * <p/>
209      * 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.
210      *
211      * @param type
212      *            full qualified service type, such as <code>_http._tcp.local.</code> .
213      * @param name
214      *            unqualified service name, such as <code>foobar</code> .
215      * @param timeout
216      *            timeout in milliseconds. Typical timeout should be 5s.
217      * @param persistent
218      *            if <code>true</code> ServiceListener.resolveService will be called whenever new new information is received.
219      * @return null if the service information cannot be obtained
220      */
221     public abstract ServiceInfo getServiceInfo(String type, String name, boolean persistent, long timeout);
222 
223     /**
224      * Request service information. The information about the service is requested and the ServiceListener.resolveService method is called as soon as it is available.
225      * <p/>
226      * Usage note: Do not call this method from the AWT event dispatcher thread. You will make the user interface unresponsive.
227      *
228      * @param type
229      *            full qualified service type, such as <code>_http._tcp.local.</code> .
230      * @param name
231      *            unqualified service name, such as <code>foobar</code> .
232      */
233     public abstract void requestServiceInfo(String type, String name);
234 
235     /**
236      * Request service information. The information about the service is requested and the ServiceListener.resolveService method is called as soon as it is available.
237      * <p/>
238      * Usage note: Do not call this method from the AWT event dispatcher thread. You will make the user interface unresponsive.
239      *
240      * @param type
241      *            full qualified service type, such as <code>_http._tcp.local.</code> .
242      * @param name
243      *            unqualified service name, such as <code>foobar</code> .
244      * @param persistent
245      *            if <code>true</code> ServiceListener.resolveService will be called whenever new new information is received.
246      */
247     public abstract void requestServiceInfo(String type, String name, boolean persistent);
248 
249     /**
250      * Request service information. The information about the service is requested and the ServiceListener.resolveService method is called as soon as it is available.
251      *
252      * @param type
253      *            full qualified service type, such as <code>_http._tcp.local.</code> .
254      * @param name
255      *            unqualified service name, such as <code>foobar</code> .
256      * @param timeout
257      *            timeout in milliseconds
258      */
259     public abstract void requestServiceInfo(String type, String name, long timeout);
260 
261     /**
262      * Request service information. The information about the service is requested and the ServiceListener.resolveService method is called as soon as it is available.
263      *
264      * @param type
265      *            full qualified service type, such as <code>_http._tcp.local.</code> .
266      * @param name
267      *            unqualified service name, such as <code>foobar</code> .
268      * @param persistent
269      *            if <code>true</code> ServiceListener.resolveService will be called whenever new new information is received.
270      * @param timeout
271      *            timeout in milliseconds
272      */
273     public abstract void requestServiceInfo(String type, String name, boolean persistent, long timeout);
274 
275     /**
276      * Listen for service types.
277      *
278      * @param listener
279      *            listener for service types
280      * @exception IOException
281      *                if there is an error in the underlying protocol, such as a TCP error.
282      */
283     public abstract void addServiceTypeListener(ServiceTypeListener listener) throws IOException;
284 
285     /**
286      * Remove listener for service types.
287      *
288      * @param listener
289      *            listener for service types
290      */
291     public abstract void removeServiceTypeListener(ServiceTypeListener listener);
292 
293     /**
294      * Listen for services of a given type. The type has to be a fully qualified type name such as <code>_http._tcp.local.</code>.
295      *
296      * @param type
297      *            full qualified service type, such as <code>_http._tcp.local.</code>.
298      * @param listener
299      *            listener for service updates
300      */
301     public abstract void addServiceListener(String type, ServiceListener listener);
302 
303     /**
304      * Remove listener for services of a given type.
305      *
306      * @param type
307      *            full qualified service type, such as <code>_http._tcp.local.</code>.
308      * @param listener
309      *            listener for service updates
310      */
311     public abstract void removeServiceListener(String type, ServiceListener listener);
312 
313     /**
314      * 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>
315      * Note that the given {@code ServiceInfo} is bound to this {@code JmDNS} instance, and should not be reused for any other {@linkplain #registerService(ServiceInfo)}.
316      *
317      * @param info
318      *            service info to register
319      * @exception IOException
320      *                if there is an error in the underlying protocol, such as a TCP error.
321      */
322     public abstract void registerService(ServiceInfo info) throws IOException;
323 
324     /**
325      * Unregister a service. The service should have been registered.
326      * <p>
327      * <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/>
328      * This is support for shared records that can be rescued by some other cooperation DNS.
329      *
330      * <pre>
331      * 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.
332      * </pre>
333      *
334      * </p>
335      *
336      * @param info
337      *            service info to remove
338      */
339     public abstract void unregisterService(ServiceInfo info);
340 
341     /**
342      * Unregister all services.
343      */
344     public abstract void unregisterAllServices();
345 
346     /**
347      * Register a service type. If this service type was not already known, all service listeners will be notified of the new service type.
348      * <p>
349      * Service types are automatically registered as they are discovered.
350      * </p>
351      *
352      * @param type
353      *            full qualified service type, such as <code>_http._tcp.local.</code>.
354      * @return <code>true</code> if the type or subtype was added, <code>false</code> if the type was already registered.
355      */
356     public abstract boolean registerServiceType(String type);
357 
358     /**
359      * List Services and serviceTypes. Debugging Only
360      *
361      * @deprecated since 3.2.2
362      */
363     @Deprecated
364     public abstract void printServices();
365 
366     /**
367      * Returns a list of service infos of the specified type.
368      *
369      * @param type
370      *            Service type name, such as <code>_http._tcp.local.</code>.
371      * @return An array of service instance.
372      */
373     public abstract ServiceInfo[] list(String type);
374 
375     /**
376      * Returns a list of service infos of the specified type.
377      *
378      * @param type
379      *            Service type name, such as <code>_http._tcp.local.</code>.
380      * @param timeout
381      *            timeout in milliseconds. Typical timeout should be 6s.
382      * @return An array of service instance.
383      */
384     public abstract ServiceInfo[] list(String type, long timeout);
385 
386     /**
387      * 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.
388      *
389      * @param type
390      *            Service type name, such as <code>_http._tcp.local.</code>.
391      * @return A dictionary of service info by subtypes.
392      */
393     public abstract Map<String, ServiceInfo[]> listBySubtype(String type);
394 
395     /**
396      * 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.
397      *
398      * @param type
399      *            Service type name, such as <code>_http._tcp.local.</code>.
400      * @param timeout
401      *            timeout in milliseconds. Typical timeout should be 6s.
402      * @return A dictionary of service info by subtypes.
403      */
404     public abstract Map<String, ServiceInfo[]> listBySubtype(String type, long timeout);
405 
406     /**
407      * Returns the instance delegate
408      *
409      * @return instance delegate
410      */
411     public abstract Delegate getDelegate();
412 
413     /**
414      * Sets the instance delegate
415      *
416      * @param value
417      *            new instance delegate
418      * @return previous instance delegate
419      */
420     public abstract Delegate setDelegate(Delegate value);
421 
422 }