1 package nl.tudelft.simulation.naming.context;
2
3 import java.io.Serializable;
4 import java.net.URL;
5 import java.rmi.AccessException;
6 import java.rmi.AlreadyBoundException;
7 import java.rmi.RemoteException;
8 import java.util.Collection;
9 import java.util.LinkedHashSet;
10 import java.util.List;
11 import java.util.Map;
12 import java.util.Set;
13
14 import javax.naming.NameNotFoundException;
15 import javax.naming.NamingException;
16
17 import org.djutils.event.EventListener;
18 import org.djutils.event.EventListenerMap;
19 import org.djutils.event.EventProducer;
20 import org.djutils.event.EventType;
21 import org.djutils.event.reference.Reference;
22 import org.djutils.event.reference.ReferenceType;
23 import org.djutils.event.rmi.RmiEventProducer;
24 import org.djutils.exceptions.Throw;
25 import org.djutils.rmi.RmiObject;
26
27 import nl.tudelft.simulation.naming.context.util.ContextUtil;
28
29
30
31
32
33
34
35
36
37
38
39
40
41 public class RemoteContext extends RmiObject implements RemoteContextInterface, EventProducer
42 {
43
44 private static final long serialVersionUID = 1L;
45
46
47 protected ContextInterface embeddedContext = null;
48
49
50 protected RemoteChangeEventProducer remoteEventProducer;
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67 public RemoteContext(final String host, final int port, final String bindingKey, final ContextInterface embeddedContext,
68 final String eventProducerBindingKey) throws RemoteException, AlreadyBoundException
69 {
70 super(host, port, bindingKey);
71 Throw.whenNull(embeddedContext, "embedded context cannot be null");
72 this.embeddedContext = embeddedContext;
73 this.remoteEventProducer = new RemoteChangeEventProducer(host, port, eventProducerBindingKey);
74 }
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89 public RemoteContext(final URL registryURL, final ContextInterface embeddedContext, final String eventProducerBindingKey)
90 throws RemoteException, AlreadyBoundException
91 {
92 super(registryURL, registryURL.getPath());
93 Throw.whenNull(embeddedContext, "embedded context cannot be null");
94 this.embeddedContext = embeddedContext;
95 String host = registryURL.getHost() == null ? "127.0.0.1" : registryURL.getHost();
96 int port = registryURL.getPort() == -1 ? 1099 : registryURL.getPort();
97 this.remoteEventProducer = new RemoteChangeEventProducer(host, port, eventProducerBindingKey);
98 }
99
100
101 @Override
102 public String getAtomicName() throws RemoteException
103 {
104 return this.embeddedContext.getAtomicName();
105 }
106
107
108 @Override
109 public ContextInterface getParent() throws RemoteException
110 {
111 return this.embeddedContext.getParent();
112 }
113
114
115 @Override
116 public ContextInterface getRootContext() throws RemoteException
117 {
118 return this.embeddedContext.getRootContext();
119 }
120
121
122 @Override
123 public String getAbsolutePath() throws RemoteException
124 {
125 return this.embeddedContext.getAbsolutePath();
126 }
127
128
129 @Override
130 public Object get(final String name) throws NamingException, RemoteException
131 {
132 return this.embeddedContext.get(name);
133 }
134
135
136 @Override
137 public Object getObject(final String key) throws NamingException, RemoteException
138 {
139 return this.embeddedContext.getObject(key);
140 }
141
142
143 @Override
144 public boolean exists(final String name) throws NamingException, RemoteException
145 {
146 return this.embeddedContext.exists(name);
147 }
148
149
150 @Override
151 public boolean hasKey(final String key) throws NamingException, RemoteException
152 {
153 return this.embeddedContext.hasKey(key);
154 }
155
156
157 @Override
158 public boolean hasObject(final Object object) throws RemoteException
159 {
160 return this.embeddedContext.hasObject(object);
161 }
162
163
164 @Override
165 public boolean isEmpty() throws RemoteException
166 {
167 return this.embeddedContext.isEmpty();
168 }
169
170
171 @Override
172 public void bind(final String name, final Object object) throws NamingException, RemoteException
173 {
174 this.embeddedContext.bind(name, object);
175 }
176
177
178 @Override
179 public void bindObject(final String key, final Object object) throws NamingException, RemoteException
180 {
181 this.embeddedContext.bindObject(key, object);
182 }
183
184
185 @Override
186 public void bindObject(final Object object) throws NamingException, RemoteException
187 {
188 this.embeddedContext.bindObject(object);
189 }
190
191
192 @Override
193 public void unbind(final String name) throws NamingException, RemoteException
194 {
195 this.embeddedContext.unbind(name);
196 }
197
198
199 @Override
200 public void unbindObject(final String key) throws NamingException, RemoteException
201 {
202 this.embeddedContext.unbindObject(key);
203 }
204
205
206 @Override
207 public void rebind(final String name, final Object object) throws NamingException, RemoteException
208 {
209 this.embeddedContext.rebind(name, object);
210 }
211
212
213 @Override
214 public void rebindObject(final String key, final Object object) throws NamingException, RemoteException
215 {
216 this.embeddedContext.rebindObject(key, object);
217 }
218
219
220 @Override
221 public void rename(final String oldName, final String newName) throws NamingException, RemoteException
222 {
223 this.embeddedContext.rename(oldName, newName);
224 }
225
226
227 @Override
228 public ContextInterface createSubcontext(final String name) throws NamingException, RemoteException
229 {
230 return this.embeddedContext.createSubcontext(name);
231 }
232
233
234 @Override
235 public void destroySubcontext(final String name) throws NamingException, RemoteException
236 {
237 this.embeddedContext.destroySubcontext(name);
238 }
239
240
241 @Override
242 public Set<String> keySet() throws RemoteException
243 {
244 return new LinkedHashSet<String>(this.embeddedContext.keySet());
245 }
246
247
248 @Override
249 public Collection<Object> values() throws RemoteException
250 {
251 return new LinkedHashSet<Object>(this.embeddedContext.values());
252 }
253
254
255 @Override
256 public Map<String, Object> bindings() throws RemoteException
257 {
258 return this.embeddedContext.bindings();
259 }
260
261
262 @Override
263 public void checkCircular(final Object newObject) throws NamingException, RemoteException
264 {
265 this.embeddedContext.checkCircular(newObject);
266 }
267
268
269 @Override
270 public void close() throws NamingException, RemoteException
271 {
272
273 this.embeddedContext.close();
274 }
275
276
277 @Override
278 public void fireObjectChangedEventValue(final Object object)
279 throws NameNotFoundException, NullPointerException, NamingException, RemoteException
280 {
281 Throw.whenNull(object, "object cannot be null");
282 fireObjectChangedEventKey(makeObjectKey(object));
283 }
284
285
286 @Override
287 public void fireObjectChangedEventKey(final String key)
288 throws NameNotFoundException, NullPointerException, NamingException, RemoteException
289 {
290 Throw.whenNull(key, "key cannot be null");
291 Throw.when(key.length() == 0 || key.contains(ContextInterface.SEPARATOR), NamingException.class,
292 "key [%s] is the empty string or key contains '/'", key);
293 if (!hasKey(key))
294 {
295 throw new NameNotFoundException("Could not find object with key " + key + " for fireObjectChangedEvent");
296 }
297 try
298 {
299 this.remoteEventProducer.fireChangedEvent(ContextInterface.OBJECT_CHANGED_EVENT,
300 new Object[] {this, key, getObject(key)});
301 }
302 catch (Exception exception)
303 {
304 throw new NamingException(exception.getMessage());
305 }
306 }
307
308
309
310
311
312
313 private String makeObjectKey(final Object object)
314 {
315 return object.toString().replace(ContextInterface.SEPARATOR, ContextInterface.REPLACE_SEPARATOR);
316 }
317
318
319 @Override
320 public String toString()
321 {
322 if (this.embeddedContext != null)
323 return this.embeddedContext.toString();
324 return "RemoteContext[null]";
325 }
326
327
328 @Override
329 public String toString(final boolean verbose) throws RemoteException
330 {
331 if (!verbose)
332 {
333 return "RemoteContext[" + getAtomicName() + "]";
334 }
335 return ContextUtil.toText(this);
336 }
337
338
339
340
341
342
343 @Override
344 public synchronized boolean addListener(final EventListener listener, final EventType eventType) throws RemoteException
345 {
346 return this.embeddedContext.addListener(listener, eventType);
347 }
348
349
350 @Override
351 public synchronized boolean addListener(final EventListener listener, final EventType eventType,
352 final ReferenceType referenceType) throws RemoteException
353 {
354 return this.embeddedContext.addListener(listener, eventType, referenceType);
355 }
356
357
358 @Override
359 public synchronized boolean addListener(final EventListener listener, final EventType eventType, final int position) throws RemoteException
360 {
361 return this.embeddedContext.addListener(listener, eventType, position);
362 }
363
364
365 @Override
366 public synchronized boolean addListener(final EventListener listener, final EventType eventType, final int position,
367 final ReferenceType referenceType) throws RemoteException
368 {
369 return this.embeddedContext.addListener(listener, eventType, position, referenceType);
370 }
371
372
373 @Override
374 public synchronized int removeAllListeners() throws RemoteException
375 {
376 return this.remoteEventProducer.removeAllListeners();
377 }
378
379
380 @Override
381 public synchronized int removeAllListeners(final Class<?> ofClass) throws RemoteException
382 {
383 return this.remoteEventProducer.removeAllListeners(ofClass);
384 }
385
386
387 @Override
388 public synchronized boolean removeListener(final EventListener listener, final EventType eventType) throws RemoteException
389 {
390 return this.embeddedContext.removeListener(listener, eventType);
391 }
392
393
394 @Override
395 public List<Reference<EventListener>> getListenerReferences(final EventType eventType) throws RemoteException
396 {
397 return this.remoteEventProducer.getListenerReferences(eventType);
398 }
399
400 @Override
401 public EventListenerMap getEventListenerMap() throws RemoteException
402 {
403 return this.remoteEventProducer.getEventListenerMap();
404 }
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422 protected class RemoteChangeEventProducer extends RmiEventProducer
423 {
424
425 private static final long serialVersionUID = 20200208L;
426
427
428 private final String bindingKey;
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444 public RemoteChangeEventProducer(final String host, final int port, final String bindingKey)
445 throws RemoteException, AlreadyBoundException
446 {
447 super(host, port, bindingKey);
448 this.bindingKey = bindingKey;
449 }
450
451
452
453
454
455
456
457 protected void fireChangedEvent(final EventType eventType, final Serializable value) throws RemoteException
458 {
459 super.fireEvent(eventType, value);
460 }
461 }
462
463 }