Coverage Report - org.apache.turbine.services.BaseServiceBroker
 
Classes in this File Line Coverage Branch Coverage Complexity
BaseServiceBroker
72%
124/170
79%
57/72
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  
 }