Clover coverage report - Code Coverage for hivemind release 1.1-beta-2
Coverage timestamp: Tue Jun 28 2005 10:28:23 EDT
file stats: LOC: 599   Methods: 33
NCLOC: 383   Classes: 1
 
 Source file Conditionals Statements Methods TOTAL
RegistryInfrastructureImpl.java 91.9% 99.5% 100% 97.6%
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  143 public RegistryInfrastructureImpl(ErrorHandler errorHandler, Locale locale)
 106    {
 107  143 _errorHandler = errorHandler;
 108  143 _locale = locale;
 109   
 110  143 _translatorManager = new TranslatorManager(this, errorHandler);
 111   
 112  143 _expander = new SymbolExpander(_errorHandler, this);
 113    }
 114   
 115  14 public Locale getLocale()
 116    {
 117  14 return _locale;
 118    }
 119   
 120  2555 public void addServicePoint(ServicePoint point)
 121    {
 122  2555 checkStarted();
 123   
 124  2555 _servicePoints.put(point.getExtensionPointId(), point);
 125   
 126  2555 addServicePointByInterface(point);
 127    }
 128   
 129  2555 private void addServicePointByInterface(ServicePoint point)
 130    {
 131  2555 String key = point.getServiceInterfaceClassName();
 132   
 133  2555 List l = (List) _servicePointsByInterfaceClassName.get(key);
 134   
 135  2555 if (l == null)
 136    {
 137  1558 l = new LinkedList();
 138  1558 _servicePointsByInterfaceClassName.put(key, l);
 139    }
 140   
 141  2555 l.add(point);
 142    }
 143   
 144  1031 public void addConfigurationPoint(ConfigurationPoint point)
 145    {
 146  1031 checkStarted();
 147   
 148  1031 _configurationPoints.put(point.getExtensionPointId(), point);
 149    }
 150   
 151  3743 public ServicePoint getServicePoint(String serviceId, Module module)
 152    {
 153  3743 checkShutdown();
 154  3743 ServicePoint result = (ServicePoint) _servicePoints.get(serviceId);
 155  3743 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  3740 if (!result.visibleToModule(module))
 182  2 throw new ApplicationRuntimeException(ImplMessages.serviceNotVisible(serviceId, module));
 183   
 184  3738 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  3229 public Object getService(String serviceId, Class serviceInterface, Module module)
 202    {
 203  3229 ServicePoint point = getServicePoint(serviceId, module);
 204   
 205  3227 return point.getService(serviceInterface);
 206    }
 207   
 208  149 public Object getService(Class serviceInterface, Module module)
 209    {
 210  149 String key = serviceInterface.getName();
 211   
 212  149 List servicePoints = (List) _servicePointsByInterfaceClassName.get(key);
 213   
 214  149 if (servicePoints == null)
 215  1 servicePoints = Collections.EMPTY_LIST;
 216   
 217  149 ServicePoint point = null;
 218  149 int count = 0;
 219   
 220  149 Iterator i = servicePoints.iterator();
 221  149 while (i.hasNext())
 222    {
 223  150 ServicePoint sp = (ServicePoint) i.next();
 224   
 225  150 if (!sp.visibleToModule(module))
 226  1 continue;
 227   
 228  149 point = sp;
 229   
 230  149 count++;
 231    }
 232   
 233  149 if (count == 0)
 234  1 throw new ApplicationRuntimeException(ImplMessages
 235    .noServicePointForInterface(serviceInterface));
 236   
 237  148 if (count > 1)
 238  1 throw new ApplicationRuntimeException(ImplMessages.multipleServicePointsForInterface(
 239    serviceInterface,
 240    servicePoints));
 241   
 242  147 return point.getService(serviceInterface);
 243    }
 244   
 245  785 public ConfigurationPoint getConfigurationPoint(String configurationId, Module module)
 246    {
 247  785 checkShutdown();
 248   
 249  784 ConfigurationPoint result = (ConfigurationPoint) _configurationPoints.get(configurationId);
 250   
 251  784 if (result == null)
 252  1 throw new ApplicationRuntimeException(ImplMessages.noSuchConfiguration(configurationId));
 253   
 254  783 if (!result.visibleToModule(module))
 255  1 throw new ApplicationRuntimeException(ImplMessages.configurationNotVisible(
 256    configurationId,
 257    module));
 258   
 259  782 return result;
 260    }
 261   
 262  538 public List getConfiguration(String configurationId, Module module)
 263    {
 264  538 ConfigurationPoint point = getConfigurationPoint(configurationId, module);
 265   
 266  535 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  7108 public String expandSymbols(String text, Location location)
 279    {
 280  7108 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  128 public void setShutdownCoordinator(ShutdownCoordinator coordinator)
 334    {
 335  128 _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  4843 private void checkShutdown()
 386    {
 387  4843 if (_shutdown)
 388  2 throw new ApplicationRuntimeException(HiveMindMessages.registryShutdown());
 389    }
 390   
 391  3709 private void checkStarted()
 392    {
 393  3709 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  123 public void startup()
 411    {
 412  123 checkStarted();
 413   
 414  122 ServiceSerializationHelper.setServiceSerializationSupport(this);
 415   
 416  122 _started = true;
 417   
 418  122 Runnable startup = (Runnable) getService("hivemind.Startup", Runnable.class, null);
 419   
 420  122 startup.run();
 421    }
 422   
 423  1404 public synchronized ServiceModelFactory getServiceModelFactory(String name)
 424    {
 425  1404 if (_serviceModelFactories == null)
 426  122 readServiceModelFactories();
 427   
 428  1404 ServiceModelFactory result = (ServiceModelFactory) _serviceModelFactories.get(name);
 429   
 430  1404 if (result == null)
 431  1 throw new ApplicationRuntimeException(ImplMessages.unknownServiceModel(name));
 432   
 433  1403 return result;
 434    }
 435   
 436  122 private void readServiceModelFactories()
 437    {
 438  122 List l = getConfiguration("hivemind.ServiceModels", null);
 439   
 440  122 _serviceModelFactories = new HashMap();
 441   
 442  122 Iterator i = l.iterator();
 443   
 444  122 while (i.hasNext())
 445    {
 446  484 ServiceModelContribution smc = (ServiceModelContribution) i.next();
 447   
 448  484 String name = smc.getName();
 449   
 450  484 _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  274 public boolean containsService(Class serviceInterface, Module module)
 475    {
 476  274 checkShutdown();
 477   
 478  274 String key = serviceInterface.getName();
 479   
 480  274 List servicePoints = (List) _servicePointsByInterfaceClassName.get(key);
 481   
 482  274 if (servicePoints == null)
 483  146 return false;
 484   
 485  128 int count = 0;
 486   
 487  128 Iterator i = servicePoints.iterator();
 488  128 while (i.hasNext())
 489    {
 490  129 ServicePoint point = (ServicePoint) i.next();
 491   
 492  129 if (point.visibleToModule(module))
 493  129 count++;
 494    }
 495   
 496  128 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  1043 public ErrorHandler getErrorHander()
 513    {
 514  1043 return _errorHandler;
 515    }
 516   
 517  8835 public Translator getTranslator(String constructor)
 518    {
 519  8835 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   
 567  1 public Module getModule( String moduleId )
 568    {
 569  7 for( Iterator i = _servicePoints.values().iterator(); i.hasNext(); )
 570    {
 571  7 final ServicePoint servicePoint = ( ServicePoint )i.next();
 572   
 573  7 if( servicePoint.getModule().getModuleId().equals( moduleId ) )
 574    {
 575  1 return servicePoint.getModule();
 576    }
 577    }
 578  0 return null;
 579    }
 580   
 581    /* (non-Javadoc)
 582    * @see org.apache.hivemind.internal.RegistryInfrastructure#getServiceIds(java.lang.Class)
 583    */
 584  3 public List getServiceIds(Class serviceInterface)
 585    {
 586  3 final List serviceIds = new LinkedList();
 587  3 for( Iterator i = _servicePoints.values().iterator(); i.hasNext(); )
 588    {
 589  3 final ServicePoint servicePoint = ( ServicePoint )i.next();
 590   
 591  3 if( servicePoint.getServiceInterface().equals( serviceInterface ) && servicePoint.visibleToModule( null ) )
 592    {
 593  2 serviceIds.add( servicePoint.getExtensionPointId() );
 594    }
 595   
 596    }
 597  3 return serviceIds;
 598    }
 599    }