001package com.github.sarxos.webcam.ds.ipcam;
002
003import java.net.MalformedURLException;
004import java.net.URI;
005import java.net.URISyntaxException;
006import java.net.URL;
007import java.util.ArrayList;
008import java.util.Collections;
009import java.util.Iterator;
010import java.util.List;
011
012import com.github.sarxos.webcam.Webcam;
013import com.github.sarxos.webcam.WebcamDevice;
014import com.github.sarxos.webcam.WebcamDiscoveryService;
015import com.github.sarxos.webcam.WebcamException;
016
017
018/**
019 * Class used to register IP camera devices.
020 * 
021 * @author Bartosz Firyn (SarXos)
022 */
023public class IpCamDeviceRegistry {
024
025        /**
026         * Contains IP cameras.
027         */
028        private static final List<IpCamDevice> DEVICES = new ArrayList<IpCamDevice>();
029
030        /**
031         * Register IP camera.
032         * 
033         * @param ipcam the IP camera to be register
034         */
035        public static IpCamDevice register(IpCamDevice ipcam) {
036
037                for (WebcamDevice d : DEVICES) {
038                        String name = ipcam.getName();
039                        if (d.getName().equals(name)) {
040                                throw new WebcamException(String.format("Webcam with name '%s' is already registered", name));
041                        }
042                }
043
044                DEVICES.add(ipcam);
045
046                rescan();
047
048                return ipcam;
049        }
050
051        public static IpCamDevice register(String name, String url, IpCamMode mode) throws MalformedURLException {
052                return register(new IpCamDevice(name, url, mode));
053        }
054
055        public static IpCamDevice register(String name, URL url, IpCamMode mode) {
056                return register(new IpCamDevice(name, url, mode));
057        }
058
059        public static IpCamDevice register(String name, String url, IpCamMode mode, IpCamAuth auth) throws MalformedURLException {
060                return register(new IpCamDevice(name, url, mode, auth));
061        }
062
063        /**
064         * Register new IP camera device.
065         * 
066         * @param name the name of the device
067         * @param url the URL to be used
068         * @param mode the camera mode to be used
069         * @param auth the optional settings if device supports authentication
070         * @return Return newly created IP camera device object
071         */
072        public static IpCamDevice register(String name, URL url, IpCamMode mode, IpCamAuth auth) {
073                return register(new IpCamDevice(name, url, mode, auth));
074        }
075
076        /**
077         * Is device registered?
078         * 
079         * @param ipcam the IP camera device
080         * @return True if device is registsred, false otherwise
081         */
082        public static boolean isRegistered(IpCamDevice ipcam) {
083
084                if (ipcam == null) {
085                        throw new IllegalArgumentException("IP camera device cannot be null");
086                }
087
088                Iterator<IpCamDevice> di = DEVICES.iterator();
089                while (di.hasNext()) {
090                        if (di.next().getName().equals(ipcam.getName())) {
091                                return true;
092                        }
093                }
094
095                return false;
096        }
097
098        /**
099         * Is device with given name registered?
100         * 
101         * @param name the name of device
102         * @return True if device is registered, false otherwise
103         */
104        public static boolean isRegistered(String name) {
105
106                if (name == null) {
107                        throw new IllegalArgumentException("Device name cannot be null");
108                }
109
110                Iterator<IpCamDevice> di = DEVICES.iterator();
111                while (di.hasNext()) {
112                        if (di.next().getName().equals(name)) {
113                                return true;
114                        }
115                }
116
117                return false;
118        }
119
120        /**
121         * Is device with given URL registered?
122         * 
123         * @param url the URL used by device
124         * @return True if device is registered, false otherwise
125         */
126        public static boolean isRegistered(URL url) {
127
128                if (url == null) {
129                        throw new IllegalArgumentException("Camera device URL cannot be null");
130                }
131
132                try {
133                        return isRegistered(url.toURI());
134                } catch (URISyntaxException e) {
135                        throw new WebcamException(e);
136                }
137        }
138
139        /**
140         * Is device with given URL registered?
141         * 
142         * @param url the URL used by device
143         * @return True if device is registered, false otherwise
144         */
145        public static boolean isRegistered(URI uri) {
146
147                if (uri == null) {
148                        throw new IllegalArgumentException("Camera device URI cannot be null");
149                }
150
151                for (IpCamDevice d : DEVICES) {
152
153                        // URL.euals() method is broken and thus we shall not depend on
154                        // it, the best w/a is to use URI instead
155
156                        try {
157                                if (d.getURL().toURI().equals(uri)) {
158                                        return true;
159                                }
160                        } catch (URISyntaxException e) {
161                                throw new WebcamException(e);
162                        }
163                }
164
165                return false;
166        }
167
168        /**
169         * Unregister IP camera.
170         * 
171         * @param ipcam the IP camera to be unregister
172         */
173        public static boolean unregister(IpCamDevice ipcam) {
174                try {
175                        return DEVICES.remove(ipcam);
176                } finally {
177                        rescan();
178                }
179        }
180
181        /**
182         * Run discovery service once if device has been removed to trigger
183         * disconnected webcam discovery event and keep webcams list up-to-date.
184         */
185        private static void rescan() {
186                WebcamDiscoveryService discovery = Webcam.getDiscoveryServiceRef();
187                if (discovery != null) {
188                        discovery.scan();
189                }
190        }
191
192        /**
193         * Unregister IP camera with given name.
194         * 
195         * @param ipcam the IP camera to be unregister
196         */
197        public static boolean unregister(String name) {
198                Iterator<IpCamDevice> di = DEVICES.iterator();
199                while (di.hasNext()) {
200                        IpCamDevice d = di.next();
201                        if (d.getName().equals(name)) {
202                                di.remove();
203                                rescan();
204                                return true;
205                        }
206                }
207                return false;
208        }
209
210        /**
211         * Get all registered IP cameras.
212         * 
213         * @return Collection of registered IP cameras
214         */
215        public static List<IpCamDevice> getIpCameras() {
216                return Collections.unmodifiableList(DEVICES);
217        }
218
219        /**
220         * Removes all registered devices.
221         */
222        public static void unregisterAll() {
223                DEVICES.clear();
224                rescan();
225        }
226}