1 /*
2 Copyright (C) 2007 Dirk Huenniger
3
4 This library is free software; you can redistribute it and/or
5 modify it under the terms of the GNU Lesser General Public
6 License as published by the Free Software Foundation; either
7 version 2.1 of the License, or (at your option) any later version.
8
9 This library is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 Lesser General Public License for more details.
13
14 You should have received a copy of the GNU Lesser General Public
15 License along with this library; if not, write to the Free Software
16 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
17 */
18 package org.indi.server;
19
20 import java.util.HashSet;
21 import java.util.Set;
22
23 import org.indi.clientmessages.GetProperties;
24 import org.indi.objects.BlobVector;
25 import org.indi.objects.Message;
26 import org.indi.objects.NumberVector;
27 import org.indi.objects.SwitchVector;
28 import org.indi.objects.TextVector;
29 import org.indi.objects.TransferType;
30 import org.indi.objects.Vector;
31 import org.indi.reactor.SimpleTimer;
32
33 /**
34 * Basic implementation of the device interface. Each device driver usually
35 * inherits from this class.
36 *
37 * @author Dirk Hünniger
38 *
39 */
40 public class BasicDevice implements Device {
41 /**
42 * the indiserver instance that this driver interacting with
43 */
44 protected IndiServer server;
45 /**
46 * the name of this driver
47 */
48 protected String name = null;
49 /**
50 * A set registered observers, obsering changes of this device
51 */
52 protected Set<Observer> observers;
53
54 /**
55 * class constructor
56 *
57 * @param server
58 * the indiserver to interact with
59 */
60 public BasicDevice(IndiServer server) {
61 this.server = server;
62 this.observers = new HashSet<Observer>();
63 server.addDriver(this);
64 }
65
66 /**
67 * called by the server when a new SwitchVector (request to set the state of
68 * a switch) is received from the a client.
69 */
70 public void onNew(SwitchVector vector) {
71 }
72
73 /**
74 * called by the server when a new NumberVector (request to set the state of
75 * a number) is received from the a client.
76 */
77 public void onNew(NumberVector vector) {
78 }
79
80 /**
81 * called by the server when a new BLOB is received from the a client.
82 */
83 public void onNew(BlobVector vector) {
84 }
85
86 /**
87 * called by the server when a new TestVector (request to set the state of a
88 * text) is received from the a client.
89 */
90 public void onNew(TextVector vector) {
91 }
92
93 /**
94 * called by the server when a new GetProperties (request to send all defXXX
95 * messages) is received from the a client.
96 */
97 public void onGetProperties(GetProperties o) {
98 }
99
100 /**
101 * called by the reactor when the a timer registered with this callback
102 * expires
103 */
104 public void onTimer() {
105 }
106
107 /**
108 * Register a new observer callback with the server. The method onObserved
109 * of this class will be called whenever the given property changes.
110 *
111 * @param device
112 * The name of the device to observe
113 * @param name
114 * The name of the property to observe
115 * @param state
116 * The observerstate object destribing to listen for state or
117 * value changes or both.
118 * @return The newly created obserer object describing that this object is
119 * to be called back if the observed property changes
120 */
121 public Observer subscribe(String device, String name, ObserverState state) {
122 Observer o = new SimpleObserver(device, name, state, this);
123 this.observers.add(o);
124 this.server.addObserver(o);
125 return o;
126 }
127
128 /**
129 * remove the given observer. Thus cancel the callbacks for state or value
130 * changes
131 *
132 * @param o
133 * The obsever object to describing the subscibtrion to be
134 * canceled
135 */
136 public void unsubscribe(Observer o) {
137 this.observers.remove(o);
138 this.server.removeObserver(o);
139 }
140
141 /**
142 * cancel the callback(s) for state or value changes for the property
143 * defined by the name of the device and the name of the property.
144 *
145 * @param device
146 * The name of the device
147 * @param name
148 * The name of the property
149 */
150 public void unsubscribe(String device, String name) {
151 Set<Observer> s = new HashSet<Observer>();
152 for (Observer o : this.observers) {
153 if (o.getDevice().equals(device) && o.getName().equals(name)) {
154 s.add(o);
155 }
156 }
157 for (Observer o : s) {
158 unsubscribe(o);
159 }
160 }
161
162 /**
163 * Shortcut to send a def vector message to all interested clients
164 *
165 * @param vector
166 * The vector to be send
167 * @param message
168 * The message string to be sent with the vector
169 */
170 public void def(Vector vector, String message) {
171 sendToClients(vector, TransferType.Def, message);
172 }
173
174 /**
175 * Shortcut to send a set vector message to all interested clients
176 *
177 * @param vector
178 * The vector to be send
179 * @param message
180 * The message string to be sent with the vector
181 */
182 public void set(Vector vector, String message) {
183 sendToClients(vector, TransferType.Set, message);
184 }
185
186 /**
187 * Shortcut to send a del vector message to all interested clients
188 *
189 * @param vector
190 * The vector to be send
191 * @param message
192 * The message string to be sent with the vector
193 */
194 public void del(Vector vector, String message) {
195 sendToClients(vector, TransferType.Del, message);
196 }
197
198 /**
199 * Shortcut to send a message to all interested clients
200 *
201 * @param message
202 * The message string to be sent
203 */
204 public void msg(String message) {
205 sendToClients(new Message(this.name), TransferType.Message, message);
206 }
207
208 /**
209 * register a timer such the onTimer will be called after the given timeout
210 *
211 * @param timeout
212 * the time to wait before calling onTimer in milliseconds
213 */
214 public void timer(long timeout) {
215 this.server.reactor.register(new SimpleTimer(this, timeout));
216 }
217
218 /**
219 * Send a def vector message to all interested clients.
220 *
221 * @param vector
222 * the vector to be send.
223 */
224 public void def(Vector vector) {
225 def(vector, null);
226 }
227
228 /**
229 * Send a set vector message to all interested clients.
230 *
231 * @param vector
232 * the vector to be send.
233 */
234 public void set(Vector vector) {
235 set(vector, null);
236 }
237
238 /**
239 * Send a del vector message to all interested clients.
240 *
241 * @param vector
242 * the vector to be send.
243 */
244 public void del(Vector vector) {
245 del(vector, null);
246 }
247
248 /**
249 * Send to the given object to all interested clients
250 *
251 * @param object
252 * the object to be send
253 * @param type
254 * the way the object shall to be send
255 * @param message
256 * the to be send with the object
257 */
258 public void sendToClients(org.indi.objects.Object object,
259 TransferType type, String message) {
260 if (this.name == null) {
261 if (type == TransferType.Def) {
262 if (object instanceof Vector) {
263 this.name = ((Vector) object).name;
264 }
265 }
266 }
267 this.server.sendToClients(object, type, message);
268 }
269
270 /**
271 * @return the name of the device
272 */
273 public String getName() {
274 return this.name;
275 }
276
277 /**
278 * called by the indiserver when a property for which an for with a observer
279 * was install via the subscibe method has changed
280 */
281 public void onObserved(Vector vector) {
282 }
283 }