##### Coverage Report - org.apache.turbine.services.BaseServiceBroker

Classes in this File | Line Coverage | Branch Coverage | Complexity
BaseServiceBroker |
72% | 110/152
72% | 48/66
| 3.375;3,375

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