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