Classes in this File | Line Coverage | Branch Coverage | Complexity | ||||
BaseServiceBroker |
|
| 3.8;3,8 |
1 | package org.apache.turbine.services; | |
2 | ||
3 | /* | |
4 | * Licensed to the Apache Software Foundation (ASF) under one | |
5 | * or more contributor license agreements. See the NOTICE file | |
6 | * distributed with this work for additional information | |
7 | * regarding copyright ownership. The ASF licenses this file | |
8 | * to you under the Apache License, Version 2.0 (the | |
9 | * "License"); you may not use this file except in compliance | |
10 | * with the License. You may obtain a copy of the License at | |
11 | * | |
12 | * http://www.apache.org/licenses/LICENSE-2.0 | |
13 | * | |
14 | * Unless required by applicable law or agreed to in writing, | |
15 | * software distributed under the License is distributed on an | |
16 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY | |
17 | * KIND, either express or implied. See the License for the | |
18 | * specific language governing permissions and limitations | |
19 | * under the License. | |
20 | */ | |
21 | ||
22 | ||
23 | import java.util.ArrayList; | |
24 | import java.util.Enumeration; | |
25 | import java.util.Hashtable; | |
26 | import java.util.Iterator; | |
27 | import java.util.LinkedHashMap; | |
28 | import java.util.LinkedHashSet; | |
29 | import java.util.Map; | |
30 | import java.util.Set; | |
31 | ||
32 | import org.apache.commons.configuration.Configuration; | |
33 | import org.apache.commons.lang.StringUtils; | |
34 | import org.apache.commons.logging.Log; | |
35 | import org.apache.commons.logging.LogFactory; | |
36 | ||
37 | /** | |
38 | * A generic implementation of a <code>ServiceBroker</code> which | |
39 | * provides: | |
40 | * | |
41 | * <ul> | |
42 | * <li>Maintaining service name to class name mapping, allowing | |
43 | * pluggable service implementations.</li> | |
44 | * <li>Providing <code>Services</code> with a configuration based on | |
45 | * system wide configuration mechanism.</li> | |
46 | * </ul> | |
47 | * <li>Integration of TurbineServiceProviders for looking up | |
48 | * non-local services | |
49 | * </ul> | |
50 | * | |
51 | * @author <a href="mailto:burton@apache.org">Kevin Burton</a> | |
52 | * @author <a href="mailto:krzewski@e-point.pl">Rafal Krzewski</a> | |
53 | * @author <a href="mailto:dlr@finemaltcoding.com">Daniel Rall</a> | |
54 | * @author <a href="mailto:jvanzyl@apache.org">Jason van Zyl</a> | |
55 | * @author <a href="mailto:mpoeschl@marmot.at">Martin Poeschl</a> | |
56 | * @author <a href="mailto:hps@intermeta.de">Henning P. Schmiedehausen</a> | |
57 | * @version $Id: BaseServiceBroker.java 1706239 2015-10-01 13:18:35Z tv $ | |
58 | */ | |
59 | public abstract class BaseServiceBroker implements ServiceBroker | |
60 | { | |
61 | /** | |
62 | * Mapping of Service names to class names, keep order. | |
63 | */ | |
64 | 32 | private final Map<String, Class<?>> mapping = new LinkedHashMap<String, Class<?>>(); |
65 | ||
66 | /** | |
67 | * A repository of Service instances. | |
68 | */ | |
69 | 32 | private final Hashtable<String, Service> services = new Hashtable<String, Service>(); |
70 | ||
71 | /** | |
72 | * Configuration for the services broker. | |
73 | * The configuration should be set by the application | |
74 | * in which the services framework is running. | |
75 | */ | |
76 | private Configuration configuration; | |
77 | ||
78 | /** | |
79 | * A prefix for <code>Service</code> properties in | |
80 | * TurbineResource.properties. | |
81 | */ | |
82 | public static final String SERVICE_PREFIX = "services."; | |
83 | ||
84 | /** | |
85 | * A <code>Service</code> property determining its implementing | |
86 | * class name . | |
87 | */ | |
88 | public static final String CLASSNAME_SUFFIX = ".classname"; | |
89 | ||
90 | /** | |
91 | * These are objects that the parent application | |
92 | * can provide so that application specific | |
93 | * services have a mechanism to retrieve specialized | |
94 | * information. For example, in Turbine there are services | |
95 | * that require the RunData object: these services can | |
96 | * retrieve the RunData object that Turbine has placed | |
97 | * in the service manager. This alleviates us of | |
98 | * the requirement of having init(Object) all | |
99 | * together. | |
100 | */ | |
101 | 32 | private final Hashtable<String, Object> serviceObjects = new Hashtable<String, Object>(); |
102 | ||
103 | /** Logging */ | |
104 | 32 | private static Log log = LogFactory.getLog(BaseServiceBroker.class); |
105 | ||
106 | /** | |
107 | * Application root path as set by the | |
108 | * parent application. | |
109 | */ | |
110 | private String applicationRoot; | |
111 | ||
112 | /** | |
113 | * mapping from service names to instances of TurbineServiceProviders | |
114 | */ | |
115 | 32 | private final Hashtable<String, Service> serviceProviderInstanceMap = new Hashtable<String, Service>(); |
116 | ||
117 | /** | |
118 | * Default constructor, protected as to only be usable by subclasses. | |
119 | * | |
120 | * This constructor does nothing. | |
121 | */ | |
122 | protected BaseServiceBroker() | |
123 | 32 | { |
124 | // nothing to do | |
125 | 32 | } |
126 | ||
127 | /** | |
128 | * Set the configuration object for the services broker. | |
129 | * This is the configuration that contains information | |
130 | * about all services in the care of this service | |
131 | * manager. | |
132 | * | |
133 | * @param configuration Broker configuration. | |
134 | */ | |
135 | public void setConfiguration(Configuration configuration) | |
136 | { | |
137 | 42 | this.configuration = configuration; |
138 | 42 | } |
139 | ||
140 | /** | |
141 | * Get the configuration for this service manager. | |
142 | * | |
143 | * @return Broker configuration. | |
144 | */ | |
145 | public Configuration getConfiguration() | |
146 | { | |
147 | 0 | return configuration; |
148 | } | |
149 | ||
150 | /** | |
151 | * Initialize this service manager. | |
152 | * @throws InitializationException if the initialization fails | |
153 | */ | |
154 | public void init() throws InitializationException | |
155 | { | |
156 | // Check: | |
157 | // | |
158 | // 1. The configuration has been set. | |
159 | // 2. Make sure the application root has been set. | |
160 | ||
161 | // FIXME: Make some service framework exceptions to throw in | |
162 | // the event these requirements aren't satisfied. | |
163 | ||
164 | // Create the mapping between service names | |
165 | // and their classes. | |
166 | 42 | initMapping(); |
167 | ||
168 | // Start services that have their 'earlyInit' | |
169 | // property set to 'true'. | |
170 | 42 | initServices(false); |
171 | 42 | } |
172 | ||
173 | /** | |
174 | * Set an application specific service object | |
175 | * that can be used by application specific | |
176 | * services. | |
177 | * | |
178 | * @param name name of service object | |
179 | * @param value value of service object | |
180 | */ | |
181 | public void setServiceObject(String name, Object value) | |
182 | { | |
183 | 0 | serviceObjects.put(name, value); |
184 | 0 | } |
185 | ||
186 | /** | |
187 | * Get an application specific service object. | |
188 | * | |
189 | * @param name the name of the service object | |
190 | * @return Object application specific service object | |
191 | */ | |
192 | public Object getServiceObject(String name) | |
193 | { | |
194 | 0 | return serviceObjects.get(name); |
195 | } | |
196 | ||
197 | /** | |
198 | * Check recursively if the given checkIfc interface is among the implemented | |
199 | * interfaces | |
200 | * | |
201 | * @param checkIfc interface to check for | |
202 | * @param interfaces interfaces to scan | |
203 | * @return true if the interface is implemented | |
204 | */ | |
205 | private boolean checkForInterface(Class<?> checkIfc, Class<?>[] interfaces) | |
206 | { | |
207 | 2399 | for (Class<?> ifc : interfaces) |
208 | { | |
209 | 1117 | if (ifc == checkIfc) |
210 | { | |
211 | 32 | return true; |
212 | } | |
213 | ||
214 | 1085 | Class<?>[] subInterfaces = ifc.getInterfaces(); |
215 | 1085 | if (checkForInterface(checkIfc, subInterfaces)) |
216 | { | |
217 | 32 | return true; |
218 | } | |
219 | } | |
220 | ||
221 | 1282 | return false; |
222 | } | |
223 | ||
224 | /** | |
225 | * Creates a mapping between Service names and class names. | |
226 | * | |
227 | * The mapping is built according to settings present in | |
228 | * TurbineResources.properties. The entries should have the | |
229 | * following form: | |
230 | * | |
231 | * <pre> | |
232 | * services.MyService.classname=com.mycompany.MyServiceImpl | |
233 | * services.MyOtherService.classname=com.mycompany.MyOtherServiceImpl | |
234 | * </pre> | |
235 | * | |
236 | * <br> | |
237 | * | |
238 | * Generic ServiceBroker provides no Services. | |
239 | * @throws InitializationException if a service class could not be found | |
240 | */ | |
241 | protected void initMapping() throws InitializationException | |
242 | { | |
243 | // we need to temporarily store the earlyInit flags to avoid | |
244 | // ConcurrentModificationExceptions | |
245 | 42 | Map<String, String> earlyInitFlags = new LinkedHashMap<String, String>(); |
246 | ||
247 | /* | |
248 | * These keys returned in an order that corresponds | |
249 | * to the order the services are listed in | |
250 | * the TR.props. | |
251 | */ | |
252 | 42 | for (Iterator<String> keys = configuration.getKeys(); keys.hasNext();) |
253 | { | |
254 | 2873 | String key = keys.next(); |
255 | 2873 | String[] keyParts = StringUtils.split(key, "."); |
256 | ||
257 | 2873 | if ((keyParts.length == 3) |
258 | && (keyParts[0] + ".").equals(SERVICE_PREFIX) | |
259 | && ("." + keyParts[2]).equals(CLASSNAME_SUFFIX)) | |
260 | { | |
261 | 331 | String serviceKey = keyParts[1]; |
262 | 331 | log.info("Added Mapping for Service: " + serviceKey); |
263 | ||
264 | 331 | if (!mapping.containsKey(serviceKey)) |
265 | { | |
266 | 261 | String className = configuration.getString(key); |
267 | try | |
268 | { | |
269 | 261 | Class<?> clazz = Class.forName(className); |
270 | 261 | mapping.put(serviceKey, clazz); |
271 | ||
272 | // detect TurbineServiceProviders | |
273 | 261 | if (checkForInterface(TurbineServiceProvider.class, clazz.getInterfaces())) |
274 | { | |
275 | 32 | log.info("Found a TurbineServiceProvider: " + serviceKey + " - initializing it early"); |
276 | 32 | earlyInitFlags.put(SERVICE_PREFIX + serviceKey + ".earlyInit", "true"); |
277 | } | |
278 | } | |
279 | // those two errors must be passed to the VM | |
280 | 0 | catch (ThreadDeath t) |
281 | { | |
282 | 0 | throw t; |
283 | } | |
284 | 0 | catch (OutOfMemoryError t) |
285 | { | |
286 | 0 | throw t; |
287 | } | |
288 | 0 | catch (ClassNotFoundException e) |
289 | { | |
290 | 0 | throw new InitializationException("Class " + className + |
291 | " is unavailable. Check your jars and classes.", e); | |
292 | } | |
293 | 0 | catch (NoClassDefFoundError e) |
294 | { | |
295 | 0 | throw new InitializationException("Class " + className + |
296 | " is unavailable. Check your jars and classes.", e); | |
297 | 261 | } |
298 | } | |
299 | } | |
300 | 2873 | } |
301 | ||
302 | 42 | for (Map.Entry<String, String> entry : earlyInitFlags.entrySet()) |
303 | { | |
304 | 32 | configuration.setProperty(entry.getKey(), entry.getValue()); |
305 | 32 | } |
306 | 42 | } |
307 | ||
308 | /** | |
309 | * Determines whether a service is registered in the configured | |
310 | * <code>TurbineResources.properties</code>. | |
311 | * | |
312 | * @param serviceName The name of the service whose existence to check. | |
313 | * @return Registration predicate for the desired services. | |
314 | */ | |
315 | @Override | |
316 | public boolean isRegistered(String serviceName) | |
317 | { | |
318 | 26 | return (services.get(serviceName) != null); |
319 | } | |
320 | ||
321 | /** | |
322 | * Returns an Iterator over all known service names. | |
323 | * | |
324 | * @return An Iterator of service names. | |
325 | */ | |
326 | public Iterator<String> getServiceNames() | |
327 | { | |
328 | 88 | return mapping.keySet().iterator(); |
329 | } | |
330 | ||
331 | /** | |
332 | * Returns an Iterator over all known service names beginning with | |
333 | * the provided prefix. | |
334 | * | |
335 | * @param prefix The prefix against which to test. | |
336 | * @return An Iterator of service names which match the prefix. | |
337 | */ | |
338 | public Iterator<String> getServiceNames(String prefix) | |
339 | { | |
340 | 0 | Set<String> keys = new LinkedHashSet<String>(mapping.keySet()); |
341 | 0 | for(Iterator<String> key = keys.iterator(); key.hasNext();) |
342 | { | |
343 | 0 | if (!key.next().startsWith(prefix)) |
344 | { | |
345 | 0 | key.remove(); |
346 | } | |
347 | } | |
348 | ||
349 | 0 | return keys.iterator(); |
350 | } | |
351 | ||
352 | /** | |
353 | * Performs early initialization of specified service. | |
354 | * | |
355 | * @param name The name of the service (generally the | |
356 | * <code>SERVICE_NAME</code> constant of the service's interface | |
357 | * definition). | |
358 | * @exception InitializationException Initialization of this | |
359 | * service was not successful. | |
360 | */ | |
361 | @Override | |
362 | public synchronized void initService(String name) | |
363 | throws InitializationException | |
364 | { | |
365 | // Calling getServiceInstance(name) assures that the Service | |
366 | // implementation has its name and broker reference set before | |
367 | // initialization. | |
368 | 112 | Service instance = getServiceInstance(name); |
369 | ||
370 | 112 | if (!instance.getInit()) |
371 | { | |
372 | // this call might result in an indirect recursion | |
373 | 86 | instance.init(); |
374 | } | |
375 | 101 | } |
376 | ||
377 | /** | |
378 | * Performs early initialization of all services. Failed early | |
379 | * initialization of a Service may be non-fatal to the system, | |
380 | * thus any exceptions are logged and the initialization process | |
381 | * continues. | |
382 | */ | |
383 | public void initServices() | |
384 | { | |
385 | try | |
386 | { | |
387 | 0 | initServices(false); |
388 | } | |
389 | 0 | catch (InstantiationException notThrown) |
390 | { | |
391 | 0 | log.debug("Caught non fatal exception", notThrown); |
392 | } | |
393 | 0 | catch (InitializationException notThrown) |
394 | { | |
395 | 0 | log.debug("Caught non fatal exception", notThrown); |
396 | 0 | } |
397 | 0 | } |
398 | ||
399 | /** | |
400 | * Performs early initialization of all services. You can decide | |
401 | * to handle failed initializations if you wish, but then | |
402 | * after one service fails, the other will not have the chance | |
403 | * to initialize. | |
404 | * | |
405 | * @param report <code>true</code> if you want exceptions thrown. | |
406 | * @throws InstantiationException if the service could not be instantiated | |
407 | * @throws InitializationException if the service could not be initialized | |
408 | */ | |
409 | public void initServices(boolean report) | |
410 | throws InstantiationException, InitializationException | |
411 | { | |
412 | 42 | if (report) |
413 | { | |
414 | // Throw exceptions | |
415 | 0 | for (Iterator<String> names = getServiceNames(); names.hasNext();) |
416 | { | |
417 | 0 | doInitService(names.next()); |
418 | } | |
419 | } | |
420 | else | |
421 | { | |
422 | // Eat exceptions | |
423 | 42 | for (Iterator<String> names = getServiceNames(); names.hasNext();) |
424 | { | |
425 | try | |
426 | { | |
427 | 331 | doInitService(names.next()); |
428 | } | |
429 | // In case of an exception, file an error message; the | |
430 | // system may be still functional, though. | |
431 | 0 | catch (InstantiationException e) |
432 | { | |
433 | 0 | log.error(e); |
434 | } | |
435 | 11 | catch (InitializationException e) |
436 | { | |
437 | 11 | log.error(e); |
438 | 331 | } |
439 | } | |
440 | } | |
441 | 42 | log.info("Finished initializing all services!"); |
442 | 42 | } |
443 | ||
444 | /** | |
445 | * Internal utility method for use in {@link #initServices(boolean)} | |
446 | * to prevent duplication of code. | |
447 | */ | |
448 | private void doInitService(String name) | |
449 | throws InstantiationException, InitializationException | |
450 | { | |
451 | // Only start up services that have their earlyInit flag set. | |
452 | 331 | if (getConfiguration(name).getBoolean("earlyInit", false)) |
453 | { | |
454 | 112 | log.info("Start Initializing service (early): " + name); |
455 | 112 | initService(name); |
456 | 101 | log.info("Finish Initializing service (early): " + name); |
457 | } | |
458 | 320 | } |
459 | ||
460 | /** | |
461 | * Shuts down a <code>Service</code>, releasing resources | |
462 | * allocated by an <code>Service</code>, and returns it to its | |
463 | * initial (uninitialized) state. | |
464 | * | |
465 | * @param name The name of the <code>Service</code> to be | |
466 | * uninitialized. | |
467 | */ | |
468 | @Override | |
469 | public synchronized void shutdownService(String name) | |
470 | { | |
471 | try | |
472 | { | |
473 | 368 | Service service = getServiceInstance(name); |
474 | 368 | if (service != null && service.getInit()) |
475 | { | |
476 | 264 | service.shutdown(); |
477 | ||
478 | 264 | if (service.getInit() && service instanceof BaseService) |
479 | { | |
480 | // BaseService::shutdown() does this by default, | |
481 | // but could've been overriden poorly. | |
482 | 16 | ((BaseService) service).setInit(false); |
483 | } | |
484 | } | |
485 | } | |
486 | 0 | catch (InstantiationException e) |
487 | { | |
488 | // Assuming harmless -- log the error and continue. | |
489 | 0 | log.error("Shutdown of a nonexistent Service '" |
490 | + name + "' was requested", e); | |
491 | 368 | } |
492 | 368 | } |
493 | ||
494 | /** | |
495 | * Shuts down all Turbine services, releasing allocated resources and | |
496 | * returning them to their initial (uninitialized) state. | |
497 | */ | |
498 | @Override | |
499 | public void shutdownServices() | |
500 | { | |
501 | 45 | log.info("Shutting down all services!"); |
502 | ||
503 | 45 | String serviceName = null; |
504 | ||
505 | /* | |
506 | * Now we want to reverse the order of | |
507 | * this list. This functionality should be added to | |
508 | * the ExtendedProperties in the commons but | |
509 | * this will fix the problem for now. | |
510 | */ | |
511 | ||
512 | 45 | ArrayList<String> reverseServicesList = new ArrayList<String>(); |
513 | ||
514 | 45 | for (Iterator<String> serviceNames = getServiceNames(); serviceNames.hasNext();) |
515 | { | |
516 | 367 | serviceName = serviceNames.next(); |
517 | 367 | reverseServicesList.add(0, serviceName); |
518 | } | |
519 | ||
520 | 45 | for (Iterator<String> serviceNames = reverseServicesList.iterator(); serviceNames.hasNext();) |
521 | { | |
522 | 367 | serviceName = serviceNames.next(); |
523 | 367 | log.info("Shutting down service: " + serviceName); |
524 | 367 | shutdownService(serviceName); |
525 | } | |
526 | 45 | } |
527 | ||
528 | /** | |
529 | * Returns an instance of requested Service. | |
530 | * | |
531 | * @param name The name of the Service requested. | |
532 | * @return An instance of requested Service. | |
533 | * @exception InstantiationException if the service is unknown or | |
534 | * can't be initialized. | |
535 | */ | |
536 | @Override | |
537 | public Object getService(String name) throws InstantiationException | |
538 | { | |
539 | Service service; | |
540 | ||
541 | 2494 | if (this.isLocalService(name)) |
542 | { | |
543 | try | |
544 | { | |
545 | 1977 | service = getServiceInstance(name); |
546 | 1977 | if (!service.getInit()) |
547 | { | |
548 | 182 | synchronized (service.getClass()) |
549 | { | |
550 | 182 | if (!service.getInit()) |
551 | { | |
552 | 182 | log.info("Start Initializing service (late): " + name); |
553 | 182 | service.init(); |
554 | 181 | log.info("Finish Initializing service (late): " + name); |
555 | } | |
556 | 181 | } |
557 | } | |
558 | 1976 | if (!service.getInit()) |
559 | { | |
560 | // this exception will be caught & rethrown by this very method. | |
561 | // getInit() returning false indicates some initialization issue, | |
562 | // which in turn prevents the InitableBroker from passing a | |
563 | // reference to a working instance of the initable to the client. | |
564 | 0 | throw new InitializationException( |
565 | "init() failed to initialize service " + name); | |
566 | } | |
567 | 1976 | return service; |
568 | } | |
569 | 0 | catch (InitializationException e) |
570 | { | |
571 | 0 | throw new InstantiationException("Service " + name + |
572 | " failed to initialize", e); | |
573 | } | |
574 | } | |
575 | 517 | else if (this.isNonLocalService(name)) |
576 | { | |
577 | 505 | return this.getNonLocalService(name); |
578 | } | |
579 | else | |
580 | { | |
581 | 12 | throw new InstantiationException( |
582 | "ServiceBroker: unknown service " + name | |
583 | + " requested"); | |
584 | } | |
585 | } | |
586 | ||
587 | /** | |
588 | * Retrieves an instance of a Service without triggering late | |
589 | * initialization. | |
590 | * | |
591 | * Early initialization of a Service can require access to Service | |
592 | * properties. The Service must have its name and serviceBroker | |
593 | * set by then. Therefore, before calling | |
594 | * Initable.initClass(Object), the class must be instantiated with | |
595 | * InitableBroker.getInitableInstance(), and | |
596 | * Service.setServiceBroker() and Service.setName() must be | |
597 | * called. This calls for two - level accessing the Services | |
598 | * instances. | |
599 | * | |
600 | * @param name The name of the service requested. | |
601 | * @exception InstantiationException The service is unknown or | |
602 | * can't be initialized. | |
603 | */ | |
604 | protected Service getServiceInstance(String name) | |
605 | throws InstantiationException | |
606 | { | |
607 | 2457 | Service service = services.get(name); |
608 | ||
609 | 2457 | if (service == null) |
610 | { | |
611 | 261 | if (!this.isLocalService(name)) |
612 | { | |
613 | 0 | throw new InstantiationException( |
614 | "ServiceBroker: unknown service " + name | |
615 | + " requested"); | |
616 | } | |
617 | ||
618 | try | |
619 | { | |
620 | 261 | Class<?> clazz = mapping.get(name); |
621 | ||
622 | try | |
623 | { | |
624 | 261 | service = (Service) clazz.newInstance(); |
625 | ||
626 | // check if the newly created service is also a | |
627 | // service provider - if so then remember it | |
628 | 261 | if (service instanceof TurbineServiceProvider) |
629 | { | |
630 | 32 | this.serviceProviderInstanceMap.put(name,service); |
631 | } | |
632 | } | |
633 | // those two errors must be passed to the VM | |
634 | 0 | catch (ClassCastException e) |
635 | { | |
636 | 0 | throw new InstantiationException("Class " + clazz + |
637 | " doesn't implement the Service interface", e); | |
638 | } | |
639 | 0 | catch (ThreadDeath t) |
640 | { | |
641 | 0 | throw t; |
642 | } | |
643 | 0 | catch (OutOfMemoryError t) |
644 | { | |
645 | 0 | throw t; |
646 | } | |
647 | 0 | catch (Throwable t) |
648 | { | |
649 | 0 | throw new InstantiationException("Failed to instantiate " + clazz, t); |
650 | 261 | } |
651 | } | |
652 | 0 | catch (InstantiationException e) |
653 | { | |
654 | 0 | throw new InstantiationException( |
655 | "Failed to instantiate service " + name, e); | |
656 | 261 | } |
657 | 261 | service.setServiceBroker(this); |
658 | 261 | service.setName(name); |
659 | 261 | services.put(name, service); |
660 | } | |
661 | ||
662 | 2457 | return service; |
663 | } | |
664 | ||
665 | /** | |
666 | * Returns the configuration for the specified service. | |
667 | * | |
668 | * @param name The name of the service. | |
669 | * @return Configuration of requested Service. | |
670 | */ | |
671 | @Override | |
672 | public Configuration getConfiguration(String name) | |
673 | { | |
674 | 521 | return configuration.subset(SERVICE_PREFIX + name); |
675 | } | |
676 | ||
677 | /** | |
678 | * Set the application root. | |
679 | * | |
680 | * @param applicationRoot application root | |
681 | */ | |
682 | public void setApplicationRoot(String applicationRoot) | |
683 | { | |
684 | 42 | this.applicationRoot = applicationRoot; |
685 | 42 | } |
686 | ||
687 | /** | |
688 | * Get the application root as set by | |
689 | * the parent application. | |
690 | * | |
691 | * @return String application root | |
692 | */ | |
693 | public String getApplicationRoot() | |
694 | { | |
695 | 0 | return applicationRoot; |
696 | } | |
697 | ||
698 | /** | |
699 | * Determines if the requested service is managed by this | |
700 | * ServiceBroker. | |
701 | * | |
702 | * @param name The name of the Service requested. | |
703 | * @return true if the service is managed by the this ServiceBroker | |
704 | */ | |
705 | protected boolean isLocalService(String name) | |
706 | { | |
707 | 2755 | return this.mapping.containsKey(name); |
708 | } | |
709 | ||
710 | /** | |
711 | * Determines if the requested service is managed by an initialized | |
712 | * TurbineServiceProvider. We use the service names to lookup | |
713 | * the TurbineServiceProvider to ensure that we get a fully | |
714 | * inititialized service. | |
715 | * | |
716 | * @param name The name of the Service requested. | |
717 | * @return true if the service is managed by a TurbineServiceProvider | |
718 | */ | |
719 | protected boolean isNonLocalService(String name) | |
720 | { | |
721 | 517 | String serviceName = null; |
722 | 517 | TurbineServiceProvider turbineServiceProvider = null; |
723 | 517 | Enumeration<String> list = this.serviceProviderInstanceMap.keys(); |
724 | ||
725 | 529 | while (list.hasMoreElements()) |
726 | { | |
727 | 517 | serviceName = list.nextElement(); |
728 | 517 | turbineServiceProvider = (TurbineServiceProvider) this.getService(serviceName); |
729 | ||
730 | 517 | if (turbineServiceProvider.exists(name)) |
731 | { | |
732 | 505 | return true; |
733 | } | |
734 | } | |
735 | ||
736 | 12 | return false; |
737 | } | |
738 | ||
739 | /** | |
740 | * Get a non-local service managed by a TurbineServiceProvider. | |
741 | * | |
742 | * @param name The name of the Service requested. | |
743 | * @return the requested service | |
744 | * @throws InstantiationException the service couldn't be instantiated | |
745 | */ | |
746 | protected Object getNonLocalService(String name) | |
747 | throws InstantiationException | |
748 | { | |
749 | 505 | String serviceName = null; |
750 | 505 | TurbineServiceProvider turbineServiceProvider = null; |
751 | 505 | Enumeration<String> list = this.serviceProviderInstanceMap.keys(); |
752 | ||
753 | 505 | while (list.hasMoreElements()) |
754 | { | |
755 | 505 | serviceName = list.nextElement(); |
756 | 505 | turbineServiceProvider = (TurbineServiceProvider) this.getService(serviceName); |
757 | ||
758 | 505 | if (turbineServiceProvider.exists(name)) |
759 | { | |
760 | 505 | return turbineServiceProvider.get(name); |
761 | } | |
762 | } | |
763 | ||
764 | 0 | throw new InstantiationException( |
765 | "ServiceBroker: unknown non-local service " + name | |
766 | + " requested"); | |
767 | } | |
768 | } |