Clover coverage report - Code Coverage for hivemind release 1.1-beta-1
Coverage timestamp: Thu Apr 28 2005 19:53:41 EDT
file stats: LOC: 566   Methods: 31
NCLOC: 358   Classes: 1
30 day Evaluation Version distributed via the Maven Jar Repository. Clover is not free. You have 30 days to evaluate it. Please visit http://www.thecortex.net/clover to obtain a licensed version of Clover
 
 Source file Conditionals Statements Methods TOTAL
RegistryInfrastructureImpl.java 92.4% 100% 100% 98.2%
coverage coverage
 1   
 // Copyright 2004, 2005 The Apache Software Foundation
 2   
 //
 3   
 // Licensed under the Apache License, Version 2.0 (the "License");
 4   
 // you may not use this file except in compliance with the License.
 5   
 // You may obtain a copy of the License at
 6   
 //
 7   
 //     http://www.apache.org/licenses/LICENSE-2.0
 8   
 //
 9   
 // Unless required by applicable law or agreed to in writing, software
 10   
 // distributed under the License is distributed on an "AS IS" BASIS,
 11   
 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 12   
 // See the License for the specific language governing permissions and
 13   
 // limitations under the License.
 14   
 
 15   
 package org.apache.hivemind.impl;
 16   
 
 17   
 import java.util.Collections;
 18   
 import java.util.HashMap;
 19   
 import java.util.Iterator;
 20   
 import java.util.LinkedList;
 21   
 import java.util.List;
 22   
 import java.util.Locale;
 23   
 import java.util.Map;
 24   
 
 25   
 import org.apache.commons.logging.LogFactory;
 26   
 import org.apache.hivemind.ApplicationRuntimeException;
 27   
 import org.apache.hivemind.ErrorHandler;
 28   
 import org.apache.hivemind.HiveMindMessages;
 29   
 import org.apache.hivemind.Location;
 30   
 import org.apache.hivemind.ShutdownCoordinator;
 31   
 import org.apache.hivemind.SymbolSource;
 32   
 import org.apache.hivemind.SymbolSourceContribution;
 33   
 import org.apache.hivemind.internal.ConfigurationPoint;
 34   
 import org.apache.hivemind.internal.Module;
 35   
 import org.apache.hivemind.internal.RegistryInfrastructure;
 36   
 import org.apache.hivemind.internal.ServiceModelFactory;
 37   
 import org.apache.hivemind.internal.ServicePoint;
 38   
 import org.apache.hivemind.internal.ser.ServiceSerializationHelper;
 39   
 import org.apache.hivemind.internal.ser.ServiceSerializationSupport;
 40   
 import org.apache.hivemind.internal.ser.ServiceToken;
 41   
 import org.apache.hivemind.order.Orderer;
 42   
 import org.apache.hivemind.schema.Translator;
 43   
 import org.apache.hivemind.service.ThreadEventNotifier;
 44   
 import org.apache.hivemind.util.Defense;
 45   
 import org.apache.hivemind.util.PropertyUtils;
 46   
 import org.apache.hivemind.util.ToStringBuilder;
 47   
 
 48   
 /**
 49   
  * Implementation of {@link RegistryInfrastructure}.
 50   
  * 
 51   
  * @author Howard Lewis Ship
 52   
  */
 53   
 public final class RegistryInfrastructureImpl implements RegistryInfrastructure,
 54   
         ServiceSerializationSupport
 55   
 {
 56   
     private static final String SYMBOL_SOURCES = "hivemind.SymbolSources";
 57   
 
 58   
     /**
 59   
      * Map of {@link ServicePoint}keyed on fully qualified service id.
 60   
      */
 61   
     private Map _servicePoints = new HashMap();
 62   
 
 63   
     /**
 64   
      * Map of List (of {@link ServicePoint}, keyed on class name service interface.
 65   
      */
 66   
     private Map _servicePointsByInterfaceClassName = new HashMap();
 67   
 
 68   
     /**
 69   
      * Map of {@link ConfigurationPoint}keyed on fully qualified configuration id.
 70   
      */
 71   
     private Map _configurationPoints = new HashMap();
 72   
 
 73   
     private SymbolSource[] _variableSources;
 74   
 
 75   
     private ErrorHandler _errorHandler;
 76   
 
 77   
     private Locale _locale;
 78   
 
 79   
     private ShutdownCoordinator _shutdownCoordinator;
 80   
 
 81   
     /**
 82   
      * Map of {@link org.apache.hivemind.internal.ser.ServiceToken}, keyed on service id.
 83   
      * 
 84   
      * @since 1.1
 85   
      */
 86   
 
 87   
     private Map _serviceTokens;
 88   
 
 89   
     /**
 90   
      * Map of {@link ServiceModelFactory}, keyed on service model name, loaded from
 91   
      * <code>hivemind.ServiceModels</code> configuration point.
 92   
      */
 93   
     private Map _serviceModelFactories;
 94   
 
 95   
     private boolean _started = false;
 96   
 
 97   
     private boolean _shutdown = false;
 98   
 
 99   
     private ThreadEventNotifier _threadEventNotifier;
 100   
 
 101   
     private TranslatorManager _translatorManager;
 102   
 
 103   
     private SymbolExpander _expander;
 104   
 
 105  135
     public RegistryInfrastructureImpl(ErrorHandler errorHandler, Locale locale)
 106   
     {
 107  135
         _errorHandler = errorHandler;
 108  135
         _locale = locale;
 109   
 
 110  135
         _translatorManager = new TranslatorManager(this, errorHandler);
 111   
 
 112  135
         _expander = new SymbolExpander(_errorHandler, this);
 113   
     }
 114   
 
 115  13
     public Locale getLocale()
 116   
     {
 117  13
         return _locale;
 118   
     }
 119   
 
 120  2372
     public void addServicePoint(ServicePoint point)
 121   
     {
 122  2372
         checkStarted();
 123   
 
 124  2372
         _servicePoints.put(point.getExtensionPointId(), point);
 125   
 
 126  2372
         addServicePointByInterface(point);
 127   
     }
 128   
 
 129  2372
     private void addServicePointByInterface(ServicePoint point)
 130   
     {
 131  2372
         String key = point.getServiceInterfaceClassName();
 132   
 
 133  2372
         List l = (List) _servicePointsByInterfaceClassName.get(key);
 134   
 
 135  2372
         if (l == null)
 136   
         {
 137  1470
             l = new LinkedList();
 138  1470
             _servicePointsByInterfaceClassName.put(key, l);
 139   
         }
 140   
 
 141  2372
         l.add(point);
 142   
     }
 143   
 
 144  982
     public void addConfigurationPoint(ConfigurationPoint point)
 145   
     {
 146  982
         checkStarted();
 147   
 
 148  982
         _configurationPoints.put(point.getExtensionPointId(), point);
 149   
     }
 150   
 
 151  3523
     public ServicePoint getServicePoint(String serviceId, Module module)
 152   
     {
 153  3523
         checkShutdown();
 154  3523
         ServicePoint result = (ServicePoint) _servicePoints.get(serviceId);
 155  3523
         if (result == null)
 156   
         {
 157  3
             if( serviceId.indexOf( '.' ) == -1 )
 158   
             {
 159  3
                 final List possibleMatches = getMatchingServiceIds(serviceId);
 160  3
                 if( !possibleMatches.isEmpty() )
 161   
                 {
 162  2
                     final StringBuffer sb = new StringBuffer();
 163  2
                     for( Iterator i = possibleMatches.iterator(); i.hasNext(); )
 164   
                     {
 165  3
                         final String matching = ( String )i.next();
 166  3
                         sb.append( '\"' );
 167  3
                         sb.append( matching );
 168  3
                         sb.append( '\"' );
 169  3
                         if( i.hasNext() )
 170   
                         {
 171  1
                             sb.append( ", " );
 172   
                         }
 173   
                     }
 174  2
                     throw new ApplicationRuntimeException(ImplMessages.unqualifiedServicePoint(serviceId, sb.toString() ));
 175   
                 }
 176   
             }
 177  1
             throw new ApplicationRuntimeException(ImplMessages.noSuchServicePoint(serviceId));
 178   
         }
 179   
             
 180   
 
 181  3520
         if (!result.visibleToModule(module))
 182  2
             throw new ApplicationRuntimeException(ImplMessages.serviceNotVisible(serviceId, module));
 183   
 
 184  3518
         return result;
 185   
     }
 186   
 
 187  3
     private List getMatchingServiceIds(String serviceId)
 188   
     {
 189  3
         final List possibleMatches = new LinkedList();
 190  3
         for( Iterator i = _servicePoints.values().iterator(); i.hasNext(); )
 191   
         {
 192  3
             final ServicePoint servicePoint = ( ServicePoint )i.next();
 193  3
             if( servicePoint.getExtensionPointId().equals( servicePoint.getModule().getModuleId() + "." + serviceId ) )
 194   
             {
 195  3
                 possibleMatches.add( servicePoint.getExtensionPointId() );
 196   
             }
 197   
         }
 198  3
         return possibleMatches;
 199   
     }
 200   
 
 201  3041
     public Object getService(String serviceId, Class serviceInterface, Module module)
 202   
     {
 203  3041
         ServicePoint point = getServicePoint(serviceId, module);
 204   
 
 205  3039
         return point.getService(serviceInterface);
 206   
     }
 207   
 
 208  148
     public Object getService(Class serviceInterface, Module module)
 209   
     {
 210  148
         String key = serviceInterface.getName();
 211   
 
 212  148
         List servicePoints = (List) _servicePointsByInterfaceClassName.get(key);
 213   
 
 214  148
         if (servicePoints == null)
 215  1
             servicePoints = Collections.EMPTY_LIST;
 216   
 
 217  148
         ServicePoint point = null;
 218  148
         int count = 0;
 219   
 
 220  148
         Iterator i = servicePoints.iterator();
 221  148
         while (i.hasNext())
 222   
         {
 223  149
             ServicePoint sp = (ServicePoint) i.next();
 224   
 
 225  149
             if (!sp.visibleToModule(module))
 226  1
                 continue;
 227   
 
 228  148
             point = sp;
 229   
 
 230  148
             count++;
 231   
         }
 232   
 
 233  148
         if (count == 0)
 234  1
             throw new ApplicationRuntimeException(ImplMessages
 235   
                     .noServicePointForInterface(serviceInterface));
 236   
 
 237  147
         if (count > 1)
 238  1
             throw new ApplicationRuntimeException(ImplMessages.multipleServicePointsForInterface(
 239   
                     serviceInterface,
 240   
                     servicePoints));
 241   
 
 242  146
         return point.getService(serviceInterface);
 243   
     }
 244   
 
 245  749
     public ConfigurationPoint getConfigurationPoint(String configurationId, Module module)
 246   
     {
 247  749
         checkShutdown();
 248   
 
 249  748
         ConfigurationPoint result = (ConfigurationPoint) _configurationPoints.get(configurationId);
 250   
 
 251  748
         if (result == null)
 252  1
             throw new ApplicationRuntimeException(ImplMessages.noSuchConfiguration(configurationId));
 253   
 
 254  747
         if (!result.visibleToModule(module))
 255  1
             throw new ApplicationRuntimeException(ImplMessages.configurationNotVisible(
 256   
                     configurationId,
 257   
                     module));
 258   
 
 259  746
         return result;
 260   
     }
 261   
 
 262  514
     public List getConfiguration(String configurationId, Module module)
 263   
     {
 264  514
         ConfigurationPoint point = getConfigurationPoint(configurationId, module);
 265   
 
 266  511
         return point.getElements();
 267   
     }
 268   
 
 269  1
     public String toString()
 270   
     {
 271  1
         ToStringBuilder builder = new ToStringBuilder(this);
 272   
 
 273  1
         builder.append("locale", _locale);
 274   
 
 275  1
         return builder.toString();
 276   
     }
 277   
 
 278  6520
     public String expandSymbols(String text, Location location)
 279   
     {
 280  6520
         return _expander.expandSymbols(text, location);
 281   
     }
 282   
 
 283  5
     public String valueForSymbol(String name)
 284   
     {
 285  5
         checkShutdown();
 286   
 
 287  5
         SymbolSource[] sources = getSymbolSources();
 288   
 
 289  5
         for (int i = 0; i < sources.length; i++)
 290   
         {
 291  7
             String value = sources[i].valueForSymbol(name);
 292   
 
 293  7
             if (value != null)
 294  4
                 return value;
 295   
         }
 296   
 
 297  1
         return null;
 298   
     }
 299   
 
 300  5
     private synchronized SymbolSource[] getSymbolSources()
 301   
     {
 302  5
         if (_variableSources != null)
 303  2
             return _variableSources;
 304   
 
 305  3
         List contributions = getConfiguration(SYMBOL_SOURCES, null);
 306   
 
 307  3
         Orderer o = new Orderer(LogFactory.getLog(SYMBOL_SOURCES), _errorHandler, ImplMessages
 308   
                 .symbolSourceContribution());
 309   
 
 310  3
         Iterator i = contributions.iterator();
 311  3
         while (i.hasNext())
 312   
         {
 313  8
             SymbolSourceContribution c = (SymbolSourceContribution) i.next();
 314   
 
 315  8
             o.add(c, c.getName(), c.getPrecedingNames(), c.getFollowingNames());
 316   
         }
 317   
 
 318  3
         List sources = o.getOrderedObjects();
 319   
 
 320  3
         int count = sources.size();
 321   
 
 322  3
         _variableSources = new SymbolSource[count];
 323   
 
 324  3
         for (int j = 0; j < count; j++)
 325   
         {
 326  8
             SymbolSourceContribution c = (SymbolSourceContribution) sources.get(j);
 327  8
             _variableSources[j] = c.getSource();
 328   
         }
 329   
 
 330  3
         return _variableSources;
 331   
     }
 332   
 
 333  122
     public void setShutdownCoordinator(ShutdownCoordinator coordinator)
 334   
     {
 335  122
         _shutdownCoordinator = coordinator;
 336   
     }
 337   
 
 338   
     /**
 339   
      * Invokes {@link ShutdownCoordinator#shutdown()}, then releases the coordinator, modules and
 340   
      * variable sources.
 341   
      */
 342  29
     public synchronized void shutdown()
 343   
     {
 344  29
         checkShutdown();
 345   
 
 346  28
         ServiceSerializationHelper.setServiceSerializationSupport(null);
 347   
 
 348   
         // Allow service implementations and such to shutdown.
 349   
 
 350  28
         ShutdownCoordinator coordinatorService = (ShutdownCoordinator) getService(
 351   
                 "hivemind.ShutdownCoordinator",
 352   
                 ShutdownCoordinator.class,
 353   
                 null);
 354   
 
 355  28
         coordinatorService.shutdown();
 356   
 
 357   
         // TODO: Shoudl this be moved earlier?
 358   
 
 359  28
         _shutdown = true;
 360   
 
 361   
         // Shutdown infrastructure items, such as proxies.
 362   
 
 363  28
         _shutdownCoordinator.shutdown();
 364   
 
 365  28
         _servicePoints = null;
 366  28
         _servicePointsByInterfaceClassName = null;
 367  28
         _configurationPoints = null;
 368  28
         _shutdownCoordinator = null;
 369  28
         _variableSources = null;
 370  28
         _serviceModelFactories = null;
 371  28
         _threadEventNotifier = null;
 372  28
         _serviceTokens = null;
 373   
 
 374   
         // It is believed that the cache held by PropertyUtils can affect application shutdown
 375   
         // and reload in some servlet containers (such as Tomcat); this should clear that up.
 376   
 
 377  28
         PropertyUtils.clearCache();
 378   
     }
 379   
 
 380   
     /**
 381   
      * Technically, this should be a synchronized method, but the _shutdown variable hardly ever
 382   
      * changes, and the consequences are pretty minimal. See HIVEMIND-104.
 383   
      */
 384   
 
 385  4583
     private void checkShutdown()
 386   
     {
 387  4583
         if (_shutdown)
 388  2
             throw new ApplicationRuntimeException(HiveMindMessages.registryShutdown());
 389   
     }
 390   
 
 391  3471
     private void checkStarted()
 392   
     {
 393  3471
         if (_started)
 394  1
             throw new IllegalStateException(ImplMessages.registryAlreadyStarted());
 395   
     }
 396   
 
 397   
     /**
 398   
      * Starts up the Registry after all service and configuration points have been defined. This
 399   
      * locks down the Registry so that no further extension points may be added. This method may
 400   
      * only be invoked once.
 401   
      * <p>
 402   
      * This instance is stored into
 403   
      * {@link ServiceSerializationHelper#setServiceSerializationSupport(ServiceSerializationSupport)}.
 404   
      * This may cause errors (and incorrect behavior) if multiple Registries exist in a single JVM.
 405   
      * <p>
 406   
      * In addition, the service <code>hivemind.Startup</code> is obtained and <code>run()</code>
 407   
      * is invoked on it. This allows additional startup, provided in the
 408   
      * <code>hivemind.Startup</code> configuration point, to be executed.
 409   
      */
 410  117
     public void startup()
 411   
     {
 412  117
         checkStarted();
 413   
 
 414  116
         ServiceSerializationHelper.setServiceSerializationSupport(this);
 415   
 
 416  116
         _started = true;
 417   
 
 418  116
         Runnable startup = (Runnable) getService("hivemind.Startup", Runnable.class, null);
 419   
 
 420  116
         startup.run();
 421   
     }
 422   
 
 423  1326
     public synchronized ServiceModelFactory getServiceModelFactory(String name)
 424   
     {
 425  1326
         if (_serviceModelFactories == null)
 426  116
             readServiceModelFactories();
 427   
 
 428  1326
         ServiceModelFactory result = (ServiceModelFactory) _serviceModelFactories.get(name);
 429   
 
 430  1326
         if (result == null)
 431  1
             throw new ApplicationRuntimeException(ImplMessages.unknownServiceModel(name));
 432   
 
 433  1325
         return result;
 434   
     }
 435   
 
 436  116
     private void readServiceModelFactories()
 437   
     {
 438  116
         List l = getConfiguration("hivemind.ServiceModels", null);
 439   
 
 440  116
         _serviceModelFactories = new HashMap();
 441   
 
 442  116
         Iterator i = l.iterator();
 443   
 
 444  116
         while (i.hasNext())
 445   
         {
 446  460
             ServiceModelContribution smc = (ServiceModelContribution) i.next();
 447   
 
 448  460
             String name = smc.getName();
 449   
 
 450  460
             _serviceModelFactories.put(name, smc.getFactory());
 451   
         }
 452   
     }
 453   
 
 454  803
     public synchronized void cleanupThread()
 455   
     {
 456  803
         if (_threadEventNotifier == null)
 457  7
             _threadEventNotifier = (ThreadEventNotifier) getService(
 458   
                     "hivemind.ThreadEventNotifier",
 459   
                     ThreadEventNotifier.class,
 460   
                     null);
 461   
 
 462  803
         _threadEventNotifier.fireThreadCleanup();
 463   
     }
 464   
 
 465  2
     public boolean containsConfiguration(String configurationId, Module module)
 466   
     {
 467  2
         checkShutdown();
 468   
 
 469  2
         ConfigurationPoint result = (ConfigurationPoint) _configurationPoints.get(configurationId);
 470   
 
 471  2
         return result != null && result.visibleToModule(module);
 472   
     }
 473   
 
 474  270
     public boolean containsService(Class serviceInterface, Module module)
 475   
     {
 476  270
         checkShutdown();
 477   
 
 478  270
         String key = serviceInterface.getName();
 479   
 
 480  270
         List servicePoints = (List) _servicePointsByInterfaceClassName.get(key);
 481   
 
 482  270
         if (servicePoints == null)
 483  139
             return false;
 484   
 
 485  131
         int count = 0;
 486   
 
 487  131
         Iterator i = servicePoints.iterator();
 488  131
         while (i.hasNext())
 489   
         {
 490  132
             ServicePoint point = (ServicePoint) i.next();
 491   
 
 492  132
             if (point.visibleToModule(module))
 493  132
                 count++;
 494   
         }
 495   
 
 496  131
         return count == 1;
 497   
     }
 498   
 
 499  3
     public boolean containsService(String serviceId, Class serviceInterface, Module module)
 500   
     {
 501  3
         checkShutdown();
 502   
 
 503  3
         ServicePoint point = (ServicePoint) _servicePoints.get(serviceId);
 504   
 
 505  3
         if (point == null)
 506  1
             return false;
 507   
 
 508  2
         return point.visibleToModule(module)
 509   
                 && point.getServiceInterface().equals(serviceInterface);
 510   
     }
 511   
 
 512  987
     public ErrorHandler getErrorHander()
 513   
     {
 514  987
         return _errorHandler;
 515   
     }
 516   
 
 517  8151
     public Translator getTranslator(String constructor)
 518   
     {
 519  8151
         return _translatorManager.getTranslator(constructor);
 520   
     }
 521   
 
 522  1
     public Object getServiceFromToken(ServiceToken token)
 523   
     {
 524  1
         Defense.notNull(token, "token");
 525   
 
 526  1
         checkShutdown();
 527   
 
 528  1
         String serviceId = token.getServiceId();
 529   
 
 530  1
         ServicePoint sp = (ServicePoint) _servicePoints.get(serviceId);
 531   
 
 532  1
         return sp.getService(Object.class);
 533   
     }
 534   
 
 535  1
     public synchronized ServiceToken getServiceTokenForService(String serviceId)
 536   
     {
 537  1
         Defense.notNull(serviceId, "serviceId");
 538   
 
 539  1
         checkShutdown();
 540   
 
 541  1
         if (_serviceTokens == null)
 542  1
             _serviceTokens = new HashMap();
 543   
 
 544  1
         ServiceToken result = (ServiceToken) _serviceTokens.get(serviceId);
 545   
 
 546  1
         if (result == null)
 547   
         {
 548  1
             result = new ServiceToken(serviceId);
 549  1
             _serviceTokens.put(serviceId, result);
 550   
         }
 551   
 
 552  1
         return result;
 553   
     }
 554   
 
 555   
     /**
 556   
      * Sets the current RI up as the ServiceSerializationSupport. Any service proxy tokens that are
 557   
      * de-serialized will find their proxies within this Registry.
 558   
      * 
 559   
      * @since 1.1
 560   
      */
 561   
 
 562  2
     public void setupThread()
 563   
     {
 564  2
         ServiceSerializationHelper.setServiceSerializationSupport(this);
 565   
     }
 566   
 }