1 package org.apache.turbine.services;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23 import java.util.ArrayList;
24 import java.util.Enumeration;
25 import java.util.Hashtable;
26 import java.util.Iterator;
27
28 import org.apache.commons.configuration.BaseConfiguration;
29 import org.apache.commons.configuration.Configuration;
30 import org.apache.commons.lang.StringUtils;
31 import org.apache.commons.logging.Log;
32 import org.apache.commons.logging.LogFactory;
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56 public abstract class BaseServiceBroker implements ServiceBroker
57 {
58
59
60
61 private Configuration mapping = new BaseConfiguration();
62
63
64
65
66 private Hashtable<String, Service> services = new Hashtable<String, Service>();
67
68
69
70
71
72
73 private Configuration configuration;
74
75
76
77
78
79 public static final String SERVICE_PREFIX = "services.";
80
81
82
83
84
85 public static final String CLASSNAME_SUFFIX = ".classname";
86
87
88
89
90
91
92
93
94
95
96
97
98 private Hashtable<String, Object> serviceObjects = new Hashtable<String, Object>();
99
100
101 private static Log log = LogFactory.getLog(BaseServiceBroker.class);
102
103
104
105
106
107 private String applicationRoot;
108
109
110
111
112 private Hashtable<String, Service> serviceProviderInstanceMap = new Hashtable<String, Service>();
113
114
115
116
117
118
119 protected BaseServiceBroker()
120 {
121
122 }
123
124
125
126
127
128
129
130
131
132 public void setConfiguration(Configuration configuration)
133 {
134 this.configuration = configuration;
135 }
136
137
138
139
140
141
142 public Configuration getConfiguration()
143 {
144 return configuration;
145 }
146
147
148
149
150 public void init() throws InitializationException
151 {
152
153
154
155
156
157
158
159
160
161
162 initMapping();
163
164
165
166 initServices(false);
167 }
168
169
170
171
172
173
174
175
176
177 public void setServiceObject(String name, Object value)
178 {
179 serviceObjects.put(name, value);
180 }
181
182
183
184
185
186
187
188 public Object getServiceObject(String name)
189 {
190 return serviceObjects.get(name);
191 }
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209 @SuppressWarnings("unchecked")
210 protected void initMapping()
211 {
212
213
214
215
216
217
218
219
220
221
222
223
224 for (Iterator<String> keys = configuration.getKeys(); keys.hasNext();)
225 {
226 String key = keys.next();
227 String[] keyParts = StringUtils.split(key, ".");
228
229 if ((keyParts.length == 3)
230 && (keyParts[0] + ".").equals(SERVICE_PREFIX)
231 && ("." + keyParts[2]).equals(CLASSNAME_SUFFIX))
232 {
233 String serviceKey = keyParts[1];
234 log.info("Added Mapping for Service: " + serviceKey);
235
236 if (!mapping.containsKey(serviceKey))
237 {
238 mapping.setProperty(serviceKey,
239 configuration.getString(key));
240 }
241 }
242 }
243 }
244
245
246
247
248
249
250
251
252 public boolean isRegistered(String serviceName)
253 {
254 return (services.get(serviceName) != null);
255 }
256
257
258
259
260
261
262 @SuppressWarnings("unchecked")
263 public Iterator<String> getServiceNames()
264 {
265 return mapping.getKeys();
266 }
267
268
269
270
271
272
273
274
275 @SuppressWarnings("unchecked")
276 public Iterator<String> getServiceNames(String prefix)
277 {
278 return mapping.getKeys(prefix);
279 }
280
281
282
283
284
285
286
287
288
289
290 public synchronized void initService(String name)
291 throws InitializationException
292 {
293
294
295
296 Service instance = getServiceInstance(name);
297
298 if (!instance.getInit())
299 {
300
301 instance.init();
302 }
303 }
304
305
306
307
308
309
310
311 public void initServices()
312 {
313 try
314 {
315 initServices(false);
316 }
317 catch (InstantiationException notThrown)
318 {
319 log.debug("Caught non fatal exception", notThrown);
320 }
321 catch (InitializationException notThrown)
322 {
323 log.debug("Caught non fatal exception", notThrown);
324 }
325 }
326
327
328
329
330
331
332
333
334
335 public void initServices(boolean report)
336 throws InstantiationException, InitializationException
337 {
338 if (report)
339 {
340
341 for (Iterator<String> names = getServiceNames(); names.hasNext();)
342 {
343 doInitService(names.next());
344 }
345 }
346 else
347 {
348
349 for (Iterator<String> names = getServiceNames(); names.hasNext();)
350 {
351 try
352 {
353 doInitService(names.next());
354 }
355
356
357 catch (InstantiationException e)
358 {
359 log.error(e);
360 }
361 catch (InitializationException e)
362 {
363 log.error(e);
364 }
365 }
366 }
367 log.info("Finished initializing all services!");
368 }
369
370
371
372
373
374 private void doInitService(String name)
375 throws InstantiationException, InitializationException
376 {
377
378 if (getConfiguration(name).getBoolean("earlyInit", false))
379 {
380 log.info("Start Initializing service (early): " + name);
381 initService(name);
382 log.info("Finish Initializing service (early): " + name);
383 }
384 }
385
386
387
388
389
390
391
392
393
394 public synchronized void shutdownService(String name)
395 {
396 try
397 {
398 Service service = getServiceInstance(name);
399 if (service != null && service.getInit())
400 {
401 service.shutdown();
402
403 if (service.getInit() && service instanceof BaseService)
404 {
405
406
407 ((BaseService) service).setInit(false);
408 }
409 }
410 }
411 catch (InstantiationException e)
412 {
413
414 log.error("Shutdown of a nonexistent Service '"
415 + name + "' was requested", e);
416 }
417 }
418
419
420
421
422
423 public void shutdownServices()
424 {
425 log.info("Shutting down all services!");
426
427 String serviceName = null;
428
429
430
431
432
433
434
435
436 ArrayList<String> reverseServicesList = new ArrayList<String>();
437
438 for (Iterator<String> serviceNames = getServiceNames(); serviceNames.hasNext();)
439 {
440 serviceName = serviceNames.next();
441 reverseServicesList.add(0, serviceName);
442 }
443
444 for (Iterator<String> serviceNames = reverseServicesList.iterator(); serviceNames.hasNext();)
445 {
446 serviceName = serviceNames.next();
447 log.info("Shutting down service: " + serviceName);
448 shutdownService(serviceName);
449 }
450 }
451
452
453
454
455
456
457
458
459
460 public Object getService(String name) throws InstantiationException
461 {
462 Service service;
463
464 if (this.isLocalService(name))
465 {
466 try
467 {
468 service = getServiceInstance(name);
469 if (!service.getInit())
470 {
471 synchronized (service.getClass())
472 {
473 if (!service.getInit())
474 {
475 log.info("Start Initializing service (late): " + name);
476 service.init();
477 log.info("Finish Initializing service (late): " + name);
478 }
479 }
480 }
481 if (!service.getInit())
482 {
483
484
485
486
487 throw new InitializationException(
488 "init() failed to initialize service " + name);
489 }
490 return service;
491 }
492 catch (InitializationException e)
493 {
494 throw new InstantiationException("Service " + name +
495 " failed to initialize", e);
496 }
497 }
498 else if (this.isNonLocalService(name))
499 {
500 return this.getNonLocalService(name);
501 }
502 else
503 {
504 throw new InstantiationException(
505 "ServiceBroker: unknown service " + name
506 + " requested");
507 }
508 }
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527 protected Service getServiceInstance(String name)
528 throws InstantiationException
529 {
530 Service service = services.get(name);
531
532 if (service == null)
533 {
534
535 String className=null;
536 if (!this.isLocalService(name))
537 {
538 throw new InstantiationException(
539 "ServiceBroker: unknown service " + name
540 + " requested");
541 }
542 try
543 {
544 className = mapping.getString(name);
545 service = services.get(className);
546
547 if (service == null)
548 {
549 try
550 {
551 service = (Service) Class.forName(className).newInstance();
552
553
554
555 if (service instanceof TurbineServiceProvider)
556 {
557 this.serviceProviderInstanceMap.put(name,service);
558 }
559
560 }
561
562 catch (ThreadDeath t)
563 {
564 throw t;
565 }
566 catch (OutOfMemoryError t)
567 {
568 throw t;
569 }
570 catch (Throwable t)
571 {
572
573 String msg = null;
574
575 if (t instanceof NoClassDefFoundError)
576 {
577 msg = "A class referenced by " + className +
578 " is unavailable. Check your jars and classes.";
579 }
580 else if (t instanceof ClassNotFoundException)
581 {
582 msg = "Class " + className +
583 " is unavailable. Check your jars and classes.";
584 }
585 else if (t instanceof ClassCastException)
586 {
587 msg = "Class " + className +
588 " doesn't implement the Service interface";
589 }
590 else
591 {
592 msg = "Failed to instantiate " + className;
593 }
594
595 throw new InstantiationException(msg, t);
596 }
597 }
598 }
599 catch (ClassCastException e)
600 {
601 throw new InstantiationException("ServiceBroker: Class "
602 + className
603 + " does not implement Service interface.", e);
604 }
605 catch (InstantiationException e)
606 {
607 throw new InstantiationException(
608 "Failed to instantiate service " + name, e);
609 }
610 service.setServiceBroker(this);
611 service.setName(name);
612 services.put(name, service);
613 }
614
615 return service;
616 }
617
618
619
620
621
622
623
624 public Configuration getConfiguration(String name)
625 {
626 return configuration.subset(SERVICE_PREFIX + name);
627 }
628
629
630
631
632
633
634 public void setApplicationRoot(String applicationRoot)
635 {
636 this.applicationRoot = applicationRoot;
637 }
638
639
640
641
642
643
644
645 public String getApplicationRoot()
646 {
647 return applicationRoot;
648 }
649
650
651
652
653
654
655
656
657 protected boolean isLocalService(String name)
658 {
659 return this.mapping.containsKey(name);
660 }
661
662
663
664
665
666
667
668
669
670
671 protected boolean isNonLocalService(String name)
672 {
673 String serviceName = null;
674 TurbineServiceProvider turbineServiceProvider = null;
675 Enumeration<String> list = this.serviceProviderInstanceMap.keys();
676
677 while (list.hasMoreElements())
678 {
679 serviceName = list.nextElement();
680 turbineServiceProvider = (TurbineServiceProvider) this.getService(serviceName);
681
682 if (turbineServiceProvider.exists(name))
683 {
684 return true;
685 }
686 }
687
688 return false;
689 }
690
691
692
693
694
695
696
697
698 protected Object getNonLocalService(String name)
699 throws InstantiationException
700 {
701 String serviceName = null;
702 TurbineServiceProvider turbineServiceProvider = null;
703 Enumeration<String> list = this.serviceProviderInstanceMap.keys();
704
705 while (list.hasMoreElements())
706 {
707 serviceName = list.nextElement();
708 turbineServiceProvider = (TurbineServiceProvider) this.getService(serviceName);
709
710 if (turbineServiceProvider.exists(name))
711 {
712 return turbineServiceProvider.get(name);
713 }
714 }
715
716 throw new InstantiationException(
717 "ServiceBroker: unknown non-local service " + name
718 + " requested");
719 }
720 }