1 package nl.tudelft.simulation.naming.context.event;
2
3 import java.io.IOException;
4 import java.io.InputStream;
5 import java.lang.reflect.Constructor;
6 import java.lang.reflect.InvocationTargetException;
7 import java.rmi.RemoteException;
8 import java.util.Collection;
9 import java.util.Hashtable;
10 import java.util.Map;
11 import java.util.Properties;
12 import java.util.Set;
13
14 import javax.naming.Context;
15 import javax.naming.InvalidNameException;
16 import javax.naming.NameNotFoundException;
17 import javax.naming.NamingException;
18 import javax.naming.NoInitialContextException;
19 import javax.naming.NotContextException;
20
21 import org.djutils.event.EventListener;
22 import org.djutils.event.EventListenerMap;
23 import org.djutils.event.EventType;
24 import org.djutils.event.reference.ReferenceType;
25 import org.djutils.exceptions.Throw;
26 import org.djutils.io.URLResource;
27 import org.djutils.logger.CategoryLogger;
28
29 import nl.tudelft.simulation.naming.context.ContextFactory;
30 import nl.tudelft.simulation.naming.context.ContextInterface;
31 import nl.tudelft.simulation.naming.context.util.ContextUtil;
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46 @SuppressWarnings("checkstyle:needbraces")
47 public final class InitialEventContext implements EventContext
48 {
49
50 private static final long serialVersionUID = 20200101L;
51
52
53
54
55
56
57
58
59
60
61
62 public static final String INITIAL_CONTEXT_FACTORY = "java.naming.factory.initial";
63
64
65
66
67
68
69
70
71
72
73 public static final String PROVIDER_URL = "java.naming.provider.url";
74
75
76
77
78
79
80
81
82
83
84
85
86 public static final String WRAPPED_CONTEXT_FACTORY = "wrapped.naming.factory.initial";
87
88
89 private static InitialEventContext INSTANCE;
90
91
92 protected Hashtable<?, ?> properties = null;
93
94
95
96
97
98 protected ContextInterface defaultInitCtx = null;
99
100
101 protected boolean gotDefault = false;
102
103
104 public ContextEventProducerImpl contextEventProducerImpl;
105
106
107
108
109
110
111
112
113
114 private InitialEventContext(final Hashtable<?, ?> environment, final String atomicName)
115 throws NamingException, RemoteException
116 {
117 init(environment, atomicName);
118 this.contextEventProducerImpl = new ContextEventProducerImpl(this);
119 }
120
121
122
123
124
125
126
127
128 public static InitialEventContext instantiate(final String atomicName) throws NamingException, RemoteException
129 {
130 return instantiate(null, atomicName);
131 }
132
133
134
135
136
137
138
139
140
141
142 public static InitialEventContext instantiate(final Hashtable<?, ?> environment, final String atomicName)
143 throws NamingException, RemoteException
144 {
145 if (INSTANCE != null)
146 {
147 return INSTANCE;
148 }
149
150 INSTANCE = new InitialEventContext(environment, atomicName);
151 INSTANCE.init(environment == null ? null : (Hashtable<?, ?>) environment.clone(), atomicName);
152 return INSTANCE;
153 }
154
155
156
157
158
159
160
161
162
163 protected void init(final Hashtable<?, ?> environment, final String atomicName) throws NamingException, RemoteException
164 {
165 this.properties = buildEnvironment(environment);
166 if (this.properties.get(Context.INITIAL_CONTEXT_FACTORY) != null)
167 {
168 getDefaultInitCtx(atomicName);
169 }
170 }
171
172
173
174
175
176
177
178
179
180
181 protected Hashtable<?, ?> buildEnvironment(final Hashtable<?, ?> environment)
182 {
183 Hashtable<String, String> result = new Hashtable<>();
184 String[] keys = new String[] {INITIAL_CONTEXT_FACTORY, PROVIDER_URL, WRAPPED_CONTEXT_FACTORY};
185
186
187 result.put(INITIAL_CONTEXT_FACTORY, "nl.tudelft.simulation.naming.context.JvmContextFactory");
188
189
190 Map<String, String> sysEnv = System.getenv();
191 for (String key : keys)
192 {
193 if (sysEnv.containsKey(key))
194 {
195 result.put(key, sysEnv.get(key));
196 }
197 }
198
199
200 Properties javaProps = System.getProperties();
201 for (String key : keys)
202 {
203 if (javaProps.containsKey(key))
204 {
205 result.put(key, javaProps.get(key).toString());
206 }
207 }
208
209
210 InputStream stream = URLResource.getResourceAsStream("/resources/jndi.properties");
211 if (stream != null)
212 {
213 Properties jndiProps = new Properties();
214 try
215 {
216 jndiProps.load(stream);
217 for (String key : keys)
218 {
219 if (jndiProps.containsKey(key))
220 {
221 result.put(key, jndiProps.get(key).toString());
222 }
223 }
224 }
225 catch (IOException exception)
226 {
227 CategoryLogger.always().error(exception);
228 }
229 }
230
231
232 if (environment != null)
233 {
234 for (String key : keys)
235 {
236 if (environment.containsKey(key))
237 {
238 result.put(key, environment.get(key).toString());
239 }
240 }
241 }
242
243 return result;
244 }
245
246
247
248
249
250
251
252
253
254 protected ContextInterface getDefaultInitCtx(final String atomicName) throws NamingException, RemoteException
255 {
256 try
257 {
258 if (!this.gotDefault)
259 {
260 String factoryName = this.properties.get(Context.INITIAL_CONTEXT_FACTORY).toString();
261 Throw.when(factoryName == null, NamingException.class,
262 "value of " + Context.INITIAL_CONTEXT_FACTORY + " not in properties");
263 @SuppressWarnings("unchecked")
264 Class<ContextFactory> factoryClass = (Class<ContextFactory>) Class.forName(factoryName);
265 Constructor<ContextFactory> factoryConstructor = factoryClass.getDeclaredConstructor();
266 ContextFactory factory = factoryConstructor.newInstance();
267 this.defaultInitCtx = factory.getInitialContext(this.properties, atomicName);
268 this.gotDefault = true;
269 }
270 if (this.defaultInitCtx == null)
271 {
272 throw new NoInitialContextException();
273 }
274 return this.defaultInitCtx;
275 }
276 catch (ClassNotFoundException | NoSuchMethodException | SecurityException | InstantiationException
277 | IllegalAccessException | IllegalArgumentException | InvocationTargetException exception)
278 {
279 throw new NamingException("Unable to get default initial context: " + exception.getMessage());
280 }
281 }
282
283
284
285
286
287 public Hashtable<?, ?> getEnvironment()
288 {
289 return (Hashtable<?, ?>) this.properties.clone();
290 }
291
292
293 @Override
294 public void close() throws NamingException, RemoteException
295 {
296 this.properties = null;
297 if (this.defaultInitCtx != null)
298 {
299 this.defaultInitCtx.close();
300 this.defaultInitCtx = null;
301 }
302 this.gotDefault = false;
303 }
304
305
306 @Override
307 public String getAtomicName() throws RemoteException
308 {
309 if (this.defaultInitCtx != null)
310 return this.defaultInitCtx.getAtomicName();
311 throw new RuntimeException(new NoInitialContextException());
312 }
313
314
315 @Override
316 public ContextInterface getParent() throws RemoteException
317 {
318 if (this.defaultInitCtx != null)
319 return this.defaultInitCtx.getParent();
320 throw new RuntimeException(new NoInitialContextException());
321
322 }
323
324
325 @Override
326 public ContextInterface getRootContext() throws RemoteException
327 {
328 if (this.defaultInitCtx != null)
329 return this.defaultInitCtx.getRootContext();
330 throw new RuntimeException(new NoInitialContextException());
331 }
332
333
334 @Override
335 public String getAbsolutePath() throws RemoteException
336 {
337 if (this.defaultInitCtx != null)
338 return this.defaultInitCtx.getAbsolutePath();
339 throw new RuntimeException(new NoInitialContextException());
340 }
341
342
343 @Override
344 public Object get(final String name) throws NamingException, RemoteException
345 {
346 if (this.defaultInitCtx != null)
347 return this.defaultInitCtx.get(name);
348 throw new RuntimeException(new NoInitialContextException());
349 }
350
351
352 @Override
353 public Object getObject(final String key) throws NamingException, RemoteException
354 {
355 if (this.defaultInitCtx != null)
356 return this.defaultInitCtx.getObject(key);
357 throw new NoInitialContextException();
358 }
359
360
361 @Override
362 public boolean exists(final String name) throws NamingException, RemoteException
363 {
364 if (this.defaultInitCtx != null)
365 return this.defaultInitCtx.exists(name);
366 throw new NoInitialContextException();
367 }
368
369
370 @Override
371 public boolean hasKey(final String key) throws NamingException, RemoteException
372 {
373 if (this.defaultInitCtx != null)
374 return this.defaultInitCtx.hasKey(key);
375 throw new NoInitialContextException();
376 }
377
378
379 @Override
380 public boolean hasObject(final Object object) throws RemoteException
381 {
382 if (this.defaultInitCtx != null)
383 return this.defaultInitCtx.hasObject(object);
384 throw new RuntimeException(new NoInitialContextException());
385 }
386
387
388 @Override
389 public boolean isEmpty() throws RemoteException
390 {
391 if (this.defaultInitCtx != null)
392 return this.defaultInitCtx.isEmpty();
393 throw new RuntimeException(new NoInitialContextException());
394 }
395
396
397 @Override
398 public void bind(final String name, final Object object) throws NamingException, RemoteException
399 {
400 if (this.defaultInitCtx != null)
401 this.defaultInitCtx.bind(name, object);
402 else
403 throw new NoInitialContextException();
404 }
405
406
407 @Override
408 public void bindObject(final String key, final Object object) throws NamingException, RemoteException
409 {
410 if (this.defaultInitCtx != null)
411 this.defaultInitCtx.bindObject(key, object);
412 else
413 throw new NoInitialContextException();
414 }
415
416
417 @Override
418 public void bindObject(final Object object) throws NamingException, RemoteException
419 {
420 if (this.defaultInitCtx != null)
421 this.defaultInitCtx.bindObject(object);
422 else
423 throw new NoInitialContextException();
424 }
425
426
427 @Override
428 public void unbind(final String name) throws NamingException, RemoteException
429 {
430 if (this.defaultInitCtx != null)
431 this.defaultInitCtx.unbind(name);
432 else
433 throw new NoInitialContextException();
434 }
435
436
437 @Override
438 public void unbindObject(final String key) throws NamingException, RemoteException
439 {
440 if (this.defaultInitCtx != null)
441 this.defaultInitCtx.unbindObject(key);
442 else
443 throw new NoInitialContextException();
444 }
445
446
447 @Override
448 public void rebind(final String name, final Object object) throws NamingException, RemoteException
449 {
450 if (this.defaultInitCtx != null)
451 this.defaultInitCtx.rebind(name, object);
452 else
453 throw new NoInitialContextException();
454 }
455
456
457 @Override
458 public void rebindObject(final String key, final Object object) throws NamingException, RemoteException
459 {
460 if (this.defaultInitCtx != null)
461 this.defaultInitCtx.rebindObject(key, object);
462 else
463 throw new NoInitialContextException();
464 }
465
466
467 @Override
468 public void rename(final String oldName, final String newName) throws NamingException, RemoteException
469 {
470 if (this.defaultInitCtx != null)
471 this.defaultInitCtx.rename(oldName, newName);
472 else
473 throw new NoInitialContextException();
474 }
475
476
477 @Override
478 public ContextInterface createSubcontext(final String name) throws NamingException, RemoteException
479 {
480 if (this.defaultInitCtx != null)
481 return this.defaultInitCtx.createSubcontext(name);
482 else
483 throw new NoInitialContextException();
484 }
485
486
487 @Override
488 public void destroySubcontext(final String name) throws NamingException, RemoteException
489 {
490 if (this.defaultInitCtx != null)
491 this.defaultInitCtx.destroySubcontext(name);
492 else
493 throw new NoInitialContextException();
494 }
495
496
497 @Override
498 public void checkCircular(final Object newObject) throws NamingException, RemoteException
499 {
500 if (this.defaultInitCtx != null)
501 this.defaultInitCtx.checkCircular(newObject);
502 else
503 throw new NoInitialContextException();
504 }
505
506
507 @Override
508 public Set<String> keySet() throws RemoteException
509 {
510 if (this.defaultInitCtx != null)
511 return this.defaultInitCtx.keySet();
512 throw new RuntimeException(new NoInitialContextException());
513 }
514
515
516 @Override
517 public Collection<Object> values() throws RemoteException
518 {
519 if (this.defaultInitCtx != null)
520 return this.defaultInitCtx.values();
521 throw new RuntimeException(new NoInitialContextException());
522 }
523
524
525 @Override
526 public Map<String, Object> bindings() throws RemoteException
527 {
528 if (this.defaultInitCtx != null)
529 return this.defaultInitCtx.bindings();
530 throw new RuntimeException(new NoInitialContextException());
531 }
532
533
534 @Override
535 public void fireObjectChangedEventValue(final Object object)
536 throws NameNotFoundException, NullPointerException, NamingException, RemoteException
537 {
538 if (this.defaultInitCtx != null)
539 this.defaultInitCtx.fireObjectChangedEventValue(object);
540 else
541 throw new NoInitialContextException();
542 }
543
544
545 @Override
546 public void fireObjectChangedEventKey(final String key)
547 throws NameNotFoundException, NullPointerException, NamingException, RemoteException
548 {
549 if (this.defaultInitCtx != null)
550 this.defaultInitCtx.fireObjectChangedEventKey(key);
551 else
552 throw new NoInitialContextException();
553 }
554
555
556 @Override
557 public String toString()
558 {
559 if (this.defaultInitCtx != null)
560 return "InitialEventContext[" + this.defaultInitCtx.toString() + "]";
561 return "InitialEventContext[null]";
562 }
563
564
565 @Override
566 public String toString(final boolean verbose) throws RemoteException
567 {
568 if (!verbose)
569 {
570 return "InitialEventContext[" + getAtomicName() + "]";
571 }
572 return ContextUtil.toText(this);
573 }
574
575
576
577
578
579
580 @Override
581 public synchronized boolean addListener(final EventListener listener, final EventType eventType) throws RemoteException
582 {
583 if (this.defaultInitCtx != null)
584 return this.defaultInitCtx.addListener(listener, eventType);
585 throw new RuntimeException(new NoInitialContextException());
586 }
587
588
589 @Override
590 public synchronized boolean addListener(final EventListener listener, final EventType eventType,
591 final ReferenceType referenceType) throws RemoteException
592 {
593 if (this.defaultInitCtx != null)
594 return this.defaultInitCtx.addListener(listener, eventType, referenceType);
595 throw new RuntimeException(new NoInitialContextException());
596 }
597
598
599 @Override
600 public synchronized boolean addListener(final EventListener listener, final EventType eventType, final int position)
601 throws RemoteException
602 {
603 if (this.defaultInitCtx != null)
604 return this.defaultInitCtx.addListener(listener, eventType, position);
605 throw new RuntimeException(new NoInitialContextException());
606 }
607
608
609 @Override
610 public synchronized boolean addListener(final EventListener listener, final EventType eventType, final int position,
611 final ReferenceType referenceType) throws RemoteException
612 {
613 if (this.defaultInitCtx != null)
614 return this.defaultInitCtx.addListener(listener, eventType, position, referenceType);
615 throw new RuntimeException(new NoInitialContextException());
616 }
617
618
619 @Override
620 public synchronized boolean removeListener(final EventListener listener, final EventType eventType) throws RemoteException
621 {
622 if (this.defaultInitCtx != null)
623 return this.defaultInitCtx.removeListener(listener, eventType);
624 throw new RuntimeException(new NoInitialContextException());
625 }
626
627 @Override
628 public EventListenerMap getEventListenerMap() throws RemoteException
629 {
630 if (this.defaultInitCtx != null)
631 return this.defaultInitCtx.getEventListenerMap();
632 throw new RuntimeException(new NoInitialContextException());
633 }
634
635
636
637
638
639
640 @Override
641 public boolean addListener(final EventListener listener, final String absolutePath, final ContextScope contextScope)
642 throws RemoteException, NameNotFoundException, InvalidNameException, NotContextException, NamingException,
643 NullPointerException
644 {
645 if (this.defaultInitCtx != null)
646 return this.contextEventProducerImpl.addListener(listener, absolutePath, contextScope);
647 throw new RuntimeException(new NoInitialContextException());
648 }
649
650
651 @Override
652 public boolean addListener(final EventListener listener, final String absolutePath, final ContextScope contextScope,
653 final ReferenceType referenceType) throws RemoteException, NameNotFoundException, InvalidNameException,
654 NotContextException, NamingException, NullPointerException
655 {
656 if (this.defaultInitCtx != null)
657 return this.contextEventProducerImpl.addListener(listener, absolutePath, contextScope, referenceType);
658 throw new RuntimeException(new NoInitialContextException());
659 }
660
661
662 @Override
663 public boolean addListener(final EventListener listener, final String absolutePath, final ContextScope contextScope,
664 final int position) throws RemoteException, NameNotFoundException, InvalidNameException, NotContextException,
665 NamingException, NullPointerException
666 {
667 if (this.defaultInitCtx != null)
668 return this.contextEventProducerImpl.addListener(listener, absolutePath, contextScope, position);
669 throw new RuntimeException(new NoInitialContextException());
670 }
671
672
673 @Override
674 public boolean addListener(final EventListener listener, final String absolutePath, final ContextScope contextScope,
675 final int position, final ReferenceType referenceType) throws RemoteException, NameNotFoundException,
676 InvalidNameException, NotContextException, NamingException, NullPointerException
677 {
678 if (this.defaultInitCtx != null)
679 return this.contextEventProducerImpl.addListener(listener, absolutePath, contextScope, position, referenceType);
680 throw new RuntimeException(new NoInitialContextException());
681 }
682
683
684 @Override
685 public boolean removeListener(final EventListener listener, final String absolutePath, final ContextScope contextScope)
686 throws RemoteException, InvalidNameException, NullPointerException
687 {
688 if (this.defaultInitCtx != null)
689 return this.contextEventProducerImpl.removeListener(listener, absolutePath, contextScope);
690 throw new RuntimeException(new NoInitialContextException());
691 }
692
693
694 @Override
695 public int removeAllListeners()
696 {
697 if (this.defaultInitCtx != null)
698 return this.contextEventProducerImpl.removeAllListeners();
699 throw new RuntimeException(new NoInitialContextException());
700 }
701
702 }