2009/04/15 - Apache HiveMind has been retired.

For more information, please explore the Attic.

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