1package javax.jmdns;
2
3import java.net.InetAddress;
4import java.net.NetworkInterface;
5import java.util.concurrent.atomic.AtomicReference;
6
7import javax.jmdns.impl.NetworkTopologyDiscoveryImpl;
8
9/**
10 * This class is used to resolve the list of Internet address to use when attaching JmDNS to the network.
11 * <p>
12 * To create you own filtering class for Internet Addresses you will need to implement the class and the factory delegate. These must be called before any other call to JmDNS.
13 *
14 * <pre>
15 * public static class MyNetworkTopologyDiscovery implements NetworkTopologyDiscovery {
16 *
17 *     &#064;Override
18 *     public InetAddress[] getInetAddresses() {
19 *         // TODO Auto-generated method stub
20 *         return null;
21 *     }
22 *
23 *     &#064;Override
24 *     public boolean useInetAddress(NetworkInterface networkInterface, InetAddress interfaceAddress) {
25 *         // TODO Auto-generated method stub
26 *         return false;
27 *     }
28 *
29 * }
30 *
31 * public static class MyClass implements NetworkTopologyDiscovery.Factory.ClassDelegate {
32 *     public MyClass() {
33 *         super();
34 *         NetworkTopologyDiscovery.Factory.setClassDelegate(this);
35 *
36 *         // Access JmDNS or JmmDNS
37 *     }
38 *
39 *     &#064;Override
40 *     public NetworkTopologyDiscovery newNetworkTopologyDiscovery() {
41 *         return new MyNetworkTopologyDiscovery();
42 *     }
43 *
44 * }
45 * </pre>
46 *
47 * </p>
48 *
49 * @author Pierre Frisch
50 */
51public interface NetworkTopologyDiscovery {
52
53    /**
54     * NetworkTopologyDiscovery.Factory enable the creation of new instance of NetworkTopologyDiscovery.
55     */
56    public static final class Factory {
57        private static volatile NetworkTopologyDiscovery _instance;
58
59        /**
60         * This interface defines a delegate to the NetworkTopologyDiscovery.Factory class to enable subclassing.
61         */
62        public static interface ClassDelegate {
63
64            /**
65             * Allows the delegate the opportunity to construct and return a different NetworkTopologyDiscovery.
66             *
67             * @return Should return a new NetworkTopologyDiscovery Object.
68             * @see #classDelegate()
69             * @see #setClassDelegate(ClassDelegate anObject)
70             */
71            public NetworkTopologyDiscovery newNetworkTopologyDiscovery();
72        }
73
74        private static final AtomicReference<Factory.ClassDelegate> _databaseClassDelegate = new AtomicReference<Factory.ClassDelegate>();
75
76        private Factory() {
77            super();
78        }
79
80        /**
81         * Assigns <code>delegate</code> as NetworkTopologyDiscovery's class delegate. The class delegate is optional.
82         *
83         * @param delegate
84         *            The object to set as NetworkTopologyDiscovery's class delegate.
85         * @see #classDelegate()
86         * @see JmmDNS.Factory.ClassDelegate
87         */
88        public static void setClassDelegate(Factory.ClassDelegate delegate) {
89            _databaseClassDelegate.set(delegate);
90        }
91
92        /**
93         * Returns NetworkTopologyDiscovery's class delegate.
94         *
95         * @return NetworkTopologyDiscovery's class delegate.
96         * @see #setClassDelegate(ClassDelegate anObject)
97         * @see JmmDNS.Factory.ClassDelegate
98         */
99        public static Factory.ClassDelegate classDelegate() {
100            return _databaseClassDelegate.get();
101        }
102
103        /**
104         * Returns a new instance of NetworkTopologyDiscovery using the class delegate if it exists.
105         *
106         * @return new instance of NetworkTopologyDiscovery
107         */
108        protected static NetworkTopologyDiscovery newNetworkTopologyDiscovery() {
109            NetworkTopologyDiscovery instance = null;
110            Factory.ClassDelegate delegate = _databaseClassDelegate.get();
111            if (delegate != null) {
112                instance = delegate.newNetworkTopologyDiscovery();
113            }
114            return (instance != null ? instance : new NetworkTopologyDiscoveryImpl());
115        }
116
117        /**
118         * Return the instance of the Multihommed Multicast DNS.
119         *
120         * @return the JmmDNS
121         */
122        public static NetworkTopologyDiscovery getInstance() {
123            if (_instance == null) {
124                synchronized (NetworkTopologyDiscovery.Factory.class) {
125                    if (_instance == null) {
126                        _instance = NetworkTopologyDiscovery.Factory.newNetworkTopologyDiscovery();
127                    }
128                }
129            }
130            return _instance;
131        }
132    }
133
134    /**
135     * Get all local Internet Addresses for the machine.
136     *
137     * @return Set of InetAddress
138     */
139    public abstract InetAddress[] getInetAddresses();
140
141    /**
142     * Check if a given InetAddress should be used for mDNS
143     *
144     * @param networkInterface
145     * @param interfaceAddress
146     * @return <code>true</code> is the address is to be used, <code>false</code> otherwise.
147     */
148    public boolean useInetAddress(NetworkInterface networkInterface, InetAddress interfaceAddress);
149
150    /**
151     * Locks the given InetAddress if the device requires it.
152     *
153     * @param interfaceAddress
154     */
155    public void lockInetAddress(InetAddress interfaceAddress);
156
157    /**
158     * Locks the given InetAddress if the device requires it.
159     *
160     * @param interfaceAddress
161     */
162    public void unlockInetAddress(InetAddress interfaceAddress);
163
164}