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: 724   Methods: 24
NCLOC: 467   Classes: 2
 
 Source file Conditionals Statements Methods TOTAL
RegistryInfrastructureConstructor.java 91.2% 96.2% 100% 95%
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.Collection;
 18    import java.util.HashMap;
 19    import java.util.Iterator;
 20    import java.util.List;
 21    import java.util.Locale;
 22    import java.util.Map;
 23   
 24    import org.apache.commons.logging.Log;
 25    import org.apache.hivemind.ErrorHandler;
 26    import org.apache.hivemind.Location;
 27    import org.apache.hivemind.Occurances;
 28    import org.apache.hivemind.ShutdownCoordinator;
 29    import org.apache.hivemind.conditional.EvaluationContextImpl;
 30    import org.apache.hivemind.conditional.Node;
 31    import org.apache.hivemind.conditional.Parser;
 32    import org.apache.hivemind.internal.ConfigurationPoint;
 33    import org.apache.hivemind.internal.Module;
 34    import org.apache.hivemind.internal.RegistryInfrastructure;
 35    import org.apache.hivemind.internal.ServicePoint;
 36    import org.apache.hivemind.parse.ConfigurationPointDescriptor;
 37    import org.apache.hivemind.parse.ContributionDescriptor;
 38    import org.apache.hivemind.parse.DependencyDescriptor;
 39    import org.apache.hivemind.parse.ImplementationDescriptor;
 40    import org.apache.hivemind.parse.InstanceBuilder;
 41    import org.apache.hivemind.parse.InterceptorDescriptor;
 42    import org.apache.hivemind.parse.ModuleDescriptor;
 43    import org.apache.hivemind.parse.ServicePointDescriptor;
 44    import org.apache.hivemind.schema.Schema;
 45    import org.apache.hivemind.schema.impl.SchemaImpl;
 46    import org.apache.hivemind.util.IdUtils;
 47   
 48    /**
 49    * Fed a series of {@link org.apache.hivemind.parse.ModuleDescriptor}s, this class will assemble
 50    * them into a final {@link org.apache.hivemind.internal.RegistryInfrastructure} as well as perform
 51    * some validations.
 52    * <p>
 53    * This class was extracted from {@link org.apache.hivemind.impl.RegistryBuilder}.
 54    *
 55    * @author Howard M. Lewis Ship
 56    * @since 1.1
 57    */
 58    public class RegistryInfrastructureConstructor
 59    {
 60    private ErrorHandler _errorHandler;
 61   
 62    private Log _log;
 63   
 64    private RegistryAssembly _assembly;
 65   
 66    /** @since 1.1 */
 67   
 68    private Parser _conditionalExpressionParser;
 69   
 70  129 public RegistryInfrastructureConstructor(ErrorHandler errorHandler, Log log,
 71    RegistryAssembly assembly)
 72    {
 73  129 _errorHandler = errorHandler;
 74  129 _log = log;
 75  129 _assembly = assembly;
 76    }
 77   
 78    /**
 79    * Map of {@link ModuleDescriptor} keyed on module id.
 80    */
 81   
 82    private Map _moduleDescriptors = new HashMap();
 83   
 84    /**
 85    * Map of {@link ModuleImpl} keyed on module id.
 86    */
 87    private Map _modules = new HashMap();
 88   
 89    /**
 90    * Map of {@link Schema} keyed on fully qualified module id.
 91    */
 92    private Map _schemas = new HashMap();
 93   
 94    /**
 95    * Map of {@link ServicePointImpl} keyed on fully qualified id.
 96    */
 97   
 98    private Map _servicePoints = new HashMap();
 99   
 100    /**
 101    * Map of {@link ConfigurationPointImpl} keyed on fully qualified id.
 102    */
 103   
 104    private Map _configurationPoints = new HashMap();
 105   
 106    /**
 107    * Shutdown coordinator shared by all objects.
 108    */
 109   
 110    private ShutdownCoordinator _shutdownCoordinator = new ShutdownCoordinatorImpl();
 111   
 112    /**
 113    * This class is used to check the dependencies of a ModuleDescriptor. As the checker is run it
 114    * will log errors to the ErrorHandler if dependencies don't resolve or the versions dont match.
 115    */
 116    private class ModuleDependencyChecker implements Runnable
 117    {
 118    private ModuleDescriptor _source;
 119   
 120  3 public ModuleDependencyChecker(ModuleDescriptor source)
 121    {
 122  3 _source = source;
 123    }
 124   
 125  3 public void run()
 126    {
 127  3 List dependencies = _source.getDependencies();
 128  3 int count = size(dependencies);
 129   
 130  3 for (int i = 0; i < count; i++)
 131    {
 132  3 DependencyDescriptor dependency = (DependencyDescriptor) dependencies.get(i);
 133  3 checkDependency(dependency);
 134    }
 135    }
 136   
 137  3 private void checkDependency(DependencyDescriptor dependency)
 138    {
 139  3 ModuleDescriptor requiredModule = (ModuleDescriptor) _moduleDescriptors.get(dependency
 140    .getModuleId());
 141   
 142  3 if (requiredModule == null)
 143    {
 144  1 _errorHandler.error(
 145    _log,
 146    ImplMessages.dependencyOnUnknownModule(dependency),
 147    dependency.getLocation(),
 148    null);
 149  1 return;
 150    }
 151   
 152  2 if (dependency.getVersion() != null
 153    && !dependency.getVersion().equals(requiredModule.getVersion()))
 154    {
 155  1 _errorHandler.error(
 156    _log,
 157    ImplMessages.dependencyVersionMismatch(dependency),
 158    dependency.getLocation(),
 159    null);
 160  1 return;
 161    }
 162    }
 163    }
 164   
 165    /**
 166    * Constructs the registry infrastructure, based on data collected during the prior calls to
 167    * {@link #addModuleDescriptor(ModuleDescriptor)}. Expects that all post-processing of the
 168    * {@link RegistryAssembly} has already occured.
 169    */
 170  129 public RegistryInfrastructure constructRegistryInfrastructure(Locale locale)
 171    {
 172  129 RegistryInfrastructureImpl result = new RegistryInfrastructureImpl(_errorHandler, locale);
 173   
 174  129 addServiceAndConfigurationPoints(result);
 175   
 176  129 addImplementationsAndContributions();
 177   
 178  129 checkForMissingServices();
 179   
 180  129 checkContributionCounts();
 181   
 182  129 result.setShutdownCoordinator(_shutdownCoordinator);
 183   
 184  129 addModulesToRegistry(result);
 185   
 186    // The caller is responsible for invoking startup().
 187   
 188  129 return result;
 189    }
 190   
 191  258 public void addModuleDescriptor(ModuleDescriptor md)
 192    {
 193  258 String id = md.getModuleId();
 194   
 195  258 if (_log.isDebugEnabled())
 196  28 _log.debug("Processing module " + id);
 197   
 198  258 if (_modules.containsKey(id))
 199    {
 200  1 Module existing = (Module) _modules.get(id);
 201   
 202  1 _errorHandler.error(_log, ImplMessages.duplicateModuleId(id, existing.getLocation(), md
 203    .getLocation()), null, null);
 204   
 205    // Ignore the duplicate module descriptor.
 206  1 return;
 207    }
 208   
 209  257 ModuleImpl module = new ModuleImpl();
 210   
 211  257 module.setLocation(md.getLocation());
 212  257 module.setModuleId(id);
 213  257 module.setPackageName(md.getPackageName());
 214  257 module.setClassResolver(md.getClassResolver());
 215   
 216  257 if (size(md.getDependencies()) > 0)
 217  3 _assembly.addPostProcessor(new ModuleDependencyChecker(md));
 218   
 219  257 for (Iterator schemas = md.getSchemas().iterator(); schemas.hasNext();)
 220    {
 221  296 SchemaImpl schema = (SchemaImpl) schemas.next();
 222   
 223  296 schema.setModule(module);
 224   
 225  296 _schemas.put(IdUtils.qualify(id, schema.getId()), schema);
 226    }
 227   
 228  257 _modules.put(id, module);
 229   
 230  257 _moduleDescriptors.put(id, md);
 231    }
 232   
 233  129 private void addServiceAndConfigurationPoints(RegistryInfrastructureImpl infrastructure)
 234    {
 235  129 for (Iterator i = _moduleDescriptors.values().iterator(); i.hasNext();)
 236    {
 237  257 ModuleDescriptor md = (ModuleDescriptor) i.next();
 238   
 239  257 String id = md.getModuleId();
 240   
 241  257 ModuleImpl module = (ModuleImpl) _modules.get(id);
 242   
 243  257 addServicePoints(infrastructure, module, md);
 244   
 245  257 addConfigurationPoints(infrastructure, module, md);
 246    }
 247    }
 248   
 249  257 private void addServicePoints(RegistryInfrastructureImpl infrastructure, Module module,
 250    ModuleDescriptor md)
 251    {
 252  257 String moduleId = md.getModuleId();
 253  257 List services = md.getServicePoints();
 254  257 int count = size(services);
 255   
 256  257 for (int i = 0; i < count; i++)
 257    {
 258  2565 ServicePointDescriptor sd = (ServicePointDescriptor) services.get(i);
 259   
 260  2565 String pointId = moduleId + "." + sd.getId();
 261   
 262  2565 ServicePoint existingPoint = (ServicePoint) _servicePoints.get(pointId);
 263   
 264  2565 if (existingPoint != null)
 265    {
 266  1 _errorHandler.error(_log, ImplMessages.duplicateExtensionPointId(
 267    pointId,
 268    existingPoint), sd.getLocation(), null);
 269  1 continue;
 270    }
 271   
 272  2564 if (_log.isDebugEnabled())
 273  248 _log.debug("Creating service point " + pointId);
 274   
 275    // Choose which class to instantiate based on
 276    // whether the service is create-on-first-reference
 277    // or create-on-first-use (deferred).
 278   
 279  2564 ServicePointImpl point = new ServicePointImpl();
 280   
 281  2564 point.setExtensionPointId(pointId);
 282  2564 point.setLocation(sd.getLocation());
 283  2564 point.setModule(module);
 284   
 285  2564 point.setServiceInterfaceName(sd.getInterfaceClassName());
 286   
 287  2564 point.setParametersSchema(findSchema(sd.getParametersSchema(), module, sd
 288    .getParametersSchemaId(), point.getLocation()));
 289   
 290  2564 point.setParametersCount(sd.getParametersCount());
 291  2564 point.setVisibility(sd.getVisibility());
 292   
 293  2564 point.setShutdownCoordinator(_shutdownCoordinator);
 294   
 295  2564 infrastructure.addServicePoint(point);
 296   
 297    // Save this for the second phase, where contributions
 298    // from other modules are applied.
 299   
 300  2564 _servicePoints.put(pointId, point);
 301   
 302  2564 addInternalImplementations(module, pointId, sd);
 303    }
 304    }
 305   
 306  257 private void addConfigurationPoints(RegistryInfrastructureImpl registry, Module module,
 307    ModuleDescriptor md)
 308    {
 309  257 String moduleId = md.getModuleId();
 310  257 List points = md.getConfigurationPoints();
 311  257 int count = size(points);
 312   
 313  257 for (int i = 0; i < count; i++)
 314    {
 315  1039 ConfigurationPointDescriptor cpd = (ConfigurationPointDescriptor) points.get(i);
 316   
 317  1039 String pointId = moduleId + "." + cpd.getId();
 318   
 319  1039 ConfigurationPoint existingPoint = (ConfigurationPoint) _configurationPoints
 320    .get(pointId);
 321   
 322  1039 if (existingPoint != null)
 323    {
 324  1 _errorHandler.error(_log, ImplMessages.duplicateExtensionPointId(
 325    pointId,
 326    existingPoint), cpd.getLocation(), null);
 327  1 continue;
 328    }
 329   
 330  1038 if (_log.isDebugEnabled())
 331  112 _log.debug("Creating configuration point " + pointId);
 332   
 333  1038 ConfigurationPointImpl point = new ConfigurationPointImpl();
 334   
 335  1038 point.setExtensionPointId(pointId);
 336  1038 point.setLocation(cpd.getLocation());
 337  1038 point.setModule(module);
 338  1038 point.setExpectedCount(cpd.getCount());
 339   
 340  1038 point.setContributionsSchema(findSchema(cpd.getContributionsSchema(), module, cpd
 341    .getContributionsSchemaId(), cpd.getLocation()));
 342   
 343  1038 point.setVisibility(cpd.getVisibility());
 344   
 345  1038 point.setShutdownCoordinator(_shutdownCoordinator);
 346   
 347  1038 registry.addConfigurationPoint(point);
 348   
 349    // Needed later when we reconcile the rest
 350    // of the configuration contributions.
 351   
 352  1038 _configurationPoints.put(pointId, point);
 353    }
 354    }
 355   
 356  679 private void addContributionElements(Module sourceModule, ConfigurationPointImpl point,
 357    List elements)
 358    {
 359  679 if (size(elements) == 0)
 360  0 return;
 361   
 362  679 if (_log.isDebugEnabled())
 363  73 _log
 364    .debug("Adding contributions to configuration point "
 365    + point.getExtensionPointId());
 366   
 367  679 ContributionImpl c = new ContributionImpl();
 368  679 c.setContributingModule(sourceModule);
 369  679 c.addElements(elements);
 370   
 371  679 point.addContribution(c);
 372    }
 373   
 374  129 private void addModulesToRegistry(RegistryInfrastructureImpl registry)
 375    {
 376    // Add each module to the registry.
 377   
 378  129 Iterator i = _modules.values().iterator();
 379  129 while (i.hasNext())
 380    {
 381  257 ModuleImpl module = (ModuleImpl) i.next();
 382   
 383  257 if (_log.isDebugEnabled())
 384  27 _log.debug("Adding module " + module.getModuleId() + " to registry");
 385   
 386  257 module.setRegistry(registry);
 387    }
 388    }
 389   
 390  129 private void addImplementationsAndContributions()
 391    {
 392  129 for (Iterator i = _moduleDescriptors.values().iterator(); i.hasNext();)
 393    {
 394  257 ModuleDescriptor md = (ModuleDescriptor) i.next();
 395   
 396  257 if (_log.isDebugEnabled())
 397  27 _log.debug("Adding contributions from module " + md.getModuleId());
 398   
 399  257 addImplementations(md);
 400  257 addContributions(md);
 401    }
 402    }
 403   
 404  257 private void addImplementations(ModuleDescriptor md)
 405    {
 406  257 String moduleId = md.getModuleId();
 407  257 Module sourceModule = (Module) _modules.get(moduleId);
 408   
 409  257 List implementations = md.getImplementations();
 410  257 int count = size(implementations);
 411   
 412  257 for (int i = 0; i < count; i++)
 413    {
 414  4 ImplementationDescriptor impl = (ImplementationDescriptor) implementations.get(i);
 415   
 416  4 if (!includeContribution(impl.getConditionalExpression(), sourceModule, impl
 417    .getLocation()))
 418  0 continue;
 419   
 420  4 String pointId = impl.getServiceId();
 421  4 String qualifiedId = IdUtils.qualify(moduleId, pointId);
 422   
 423  4 addImplementations(sourceModule, qualifiedId, impl);
 424    }
 425   
 426    }
 427   
 428  257 private void addContributions(ModuleDescriptor md)
 429    {
 430  257 String moduleId = md.getModuleId();
 431  257 Module sourceModule = (Module) _modules.get(moduleId);
 432   
 433  257 List contributions = md.getContributions();
 434  257 int count = size(contributions);
 435   
 436  257 for (int i = 0; i < count; i++)
 437    {
 438  683 ContributionDescriptor cd = (ContributionDescriptor) contributions.get(i);
 439   
 440  683 if (!includeContribution(cd.getConditionalExpression(), sourceModule, cd.getLocation()))
 441  2 continue;
 442   
 443  681 String pointId = cd.getConfigurationId();
 444  681 String qualifiedId = IdUtils.qualify(moduleId, pointId);
 445   
 446  681 ConfigurationPointImpl point = (ConfigurationPointImpl) _configurationPoints
 447    .get(qualifiedId);
 448   
 449  681 if (point == null)
 450    {
 451  1 _errorHandler.error(_log, ImplMessages.unknownConfigurationPoint(moduleId, cd), cd
 452    .getLocation(), null);
 453   
 454  1 continue;
 455    }
 456   
 457  680 if (!point.visibleToModule(sourceModule))
 458    {
 459  1 _errorHandler.error(_log, ImplMessages.configurationPointNotVisible(
 460    point,
 461    sourceModule), cd.getLocation(), null);
 462  1 continue;
 463    }
 464   
 465  679 addContributionElements(sourceModule, point, cd.getElements());
 466    }
 467    }
 468   
 469  3602 private Schema findSchema(SchemaImpl schema, Module module, String schemaId, Location location)
 470    {
 471  3602 if (schema != null)
 472    {
 473  858 schema.setModule(module);
 474  858 return schema;
 475    }
 476   
 477  2744 if (schemaId == null)
 478  2325 return null;
 479   
 480  419 String moduleId = module.getModuleId();
 481  419 String qualifiedId = IdUtils.qualify(moduleId, schemaId);
 482   
 483  419 return getSchema(qualifiedId, moduleId, location);
 484    }
 485   
 486  419 private Schema getSchema(String schemaId, String referencingModule, Location reference)
 487    {
 488  419 Schema schema = (Schema) _schemas.get(schemaId);
 489   
 490  419 if (schema == null)
 491  1 _errorHandler
 492    .error(_log, ImplMessages.unableToResolveSchema(schemaId), reference, null);
 493  418 else if (!schema.visibleToModule(referencingModule))
 494    {
 495  1 _errorHandler.error(
 496    _log,
 497    ImplMessages.schemaNotVisible(schemaId, referencingModule),
 498    reference,
 499    null);
 500  1 schema = null;
 501    }
 502   
 503  419 return schema;
 504    }
 505   
 506    /**
 507    * Adds internal service contributions; the contributions provided inplace with the service
 508    * definition.
 509    */
 510  2564 private void addInternalImplementations(Module sourceModule, String pointId,
 511    ServicePointDescriptor spd)
 512    {
 513  2564 InstanceBuilder builder = spd.getInstanceBuilder();
 514  2564 List interceptors = spd.getInterceptors();
 515   
 516  2564 if (builder == null && interceptors == null)
 517  4 return;
 518   
 519  2560 if (builder != null)
 520  2560 addServiceInstanceBuilder(sourceModule, pointId, builder, true);
 521   
 522  2560 if (interceptors == null)
 523  2533 return;
 524   
 525  27 int count = size(interceptors);
 526   
 527  27 for (int i = 0; i < count; i++)
 528    {
 529  27 InterceptorDescriptor id = (InterceptorDescriptor) interceptors.get(i);
 530  27 addInterceptor(sourceModule, pointId, id);
 531    }
 532    }
 533   
 534    /**
 535    * Adds ordinary service contributions.
 536    */
 537   
 538  4 private void addImplementations(Module sourceModule, String pointId, ImplementationDescriptor id)
 539    {
 540  4 InstanceBuilder builder = id.getInstanceBuilder();
 541  4 List interceptors = id.getInterceptors();
 542   
 543  4 if (builder != null)
 544  2 addServiceInstanceBuilder(sourceModule, pointId, builder, false);
 545   
 546  4 int count = size(interceptors);
 547  4 for (int i = 0; i < count; i++)
 548    {
 549  4 InterceptorDescriptor ind = (InterceptorDescriptor) interceptors.get(i);
 550   
 551  4 addInterceptor(sourceModule, pointId, ind);
 552    }
 553    }
 554   
 555    /**
 556    * Adds an {@link InstanceBuilder} to a service extension point.
 557    */
 558  2562 private void addServiceInstanceBuilder(Module sourceModule, String pointId,
 559    InstanceBuilder builder, boolean isDefault)
 560    {
 561  2562 if (_log.isDebugEnabled())
 562  247 _log.debug("Adding " + builder + " to service extension point " + pointId);
 563   
 564  2562 ServicePointImpl point = (ServicePointImpl) _servicePoints.get(pointId);
 565   
 566  2562 if (point == null)
 567    {
 568  0 _errorHandler.error(
 569    _log,
 570    ImplMessages.unknownServicePoint(sourceModule, pointId),
 571    builder.getLocation(),
 572    null);
 573  0 return;
 574    }
 575   
 576  2562 if (!point.visibleToModule(sourceModule))
 577    {
 578  1 _errorHandler.error(
 579    _log,
 580    ImplMessages.servicePointNotVisible(point, sourceModule),
 581    builder.getLocation(),
 582    null);
 583  1 return;
 584    }
 585   
 586  2561 if (point.getServiceConstructor(isDefault) != null)
 587    {
 588  0 _errorHandler.error(
 589    _log,
 590    ImplMessages.duplicateFactory(sourceModule, pointId, point),
 591    builder.getLocation(),
 592    null);
 593   
 594  0 return;
 595    }
 596   
 597  2561 point.setServiceModel(builder.getServiceModel());
 598  2561 point.setServiceConstructor(builder.createConstructor(point, sourceModule), isDefault);
 599    }
 600   
 601  31 private void addInterceptor(Module sourceModule, String pointId, InterceptorDescriptor id)
 602    {
 603  31 if (_log.isDebugEnabled())
 604  0 _log.debug("Adding " + id + " to service extension point " + pointId);
 605   
 606  31 ServicePointImpl point = (ServicePointImpl) _servicePoints.get(pointId);
 607   
 608  31 String sourceModuleId = sourceModule.getModuleId();
 609   
 610  31 if (point == null)
 611    {
 612  0 _errorHandler.error(_log, ImplMessages.unknownServicePoint(sourceModule, pointId), id
 613    .getLocation(), null);
 614   
 615  0 return;
 616    }
 617   
 618  31 if (!point.visibleToModule(sourceModule))
 619    {
 620  1 _errorHandler.error(_log, ImplMessages.servicePointNotVisible(point, sourceModule), id
 621    .getLocation(), null);
 622  1 return;
 623    }
 624   
 625  30 ServiceInterceptorContributionImpl sic = new ServiceInterceptorContributionImpl();
 626   
 627    // Allow the factory id to be unqualified, to refer to an interceptor factory
 628    // service from within the same module.
 629   
 630  30 sic.setFactoryServiceId(IdUtils.qualify(sourceModuleId, id.getFactoryServiceId()));
 631  30 sic.setLocation(id.getLocation());
 632   
 633  30 sic.setFollowingInterceptorIds(IdUtils.qualifyList(sourceModuleId, id.getBefore()));
 634  30 sic.setPrecedingInterceptorIds(IdUtils.qualifyList(sourceModuleId, id.getAfter()));
 635  30 sic.setName(id.getName() != null ? IdUtils.qualify(sourceModuleId, id.getName()) : null);
 636  30 sic.setContributingModule(sourceModule);
 637  30 sic.setParameters(id.getParameters());
 638   
 639  30 point.addInterceptorContribution(sic);
 640    }
 641   
 642    /**
 643    * Checks that each service has at service constructor.
 644    */
 645  129 private void checkForMissingServices()
 646    {
 647  129 Iterator i = _servicePoints.values().iterator();
 648  129 while (i.hasNext())
 649    {
 650  2564 ServicePointImpl point = (ServicePointImpl) i.next();
 651   
 652  2564 if (point.getServiceConstructor() != null)
 653  2561 continue;
 654   
 655  3 _errorHandler.error(_log, ImplMessages.missingService(point), null, null);
 656    }
 657    }
 658   
 659    /**
 660    * Checks that each configuration extension point has the right number of contributions.
 661    */
 662   
 663  129 private void checkContributionCounts()
 664    {
 665  129 Iterator i = _configurationPoints.values().iterator();
 666   
 667  129 while (i.hasNext())
 668    {
 669  1038 ConfigurationPointImpl point = (ConfigurationPointImpl) i.next();
 670   
 671  1038 Occurances expected = point.getExpectedCount();
 672   
 673  1038 int actual = point.getContributionCount();
 674   
 675  1038 if (expected.inRange(actual))
 676  1036 continue;
 677   
 678  2 _errorHandler.error(_log, ImplMessages.wrongNumberOfContributions(
 679    point,
 680    actual,
 681    expected), point.getLocation(), null);
 682    }
 683   
 684    }
 685   
 686    /**
 687    * Filters a contribution based on an expression. Returns true if the expression is null, or
 688    * evaluates to true. Returns false if the expression if non-null and evaluates to false, or an
 689    * exception occurs evaluating the expression.
 690    *
 691    * @param expression
 692    * to parse and evaluate
 693    * @param location
 694    * of the expression (used if an error is reported)
 695    * @since 1.1
 696    */
 697   
 698  687 private boolean includeContribution(String expression, Module module, Location location)
 699    {
 700  687 if (expression == null)
 701  684 return true;
 702   
 703  3 if (_conditionalExpressionParser == null)
 704  3 _conditionalExpressionParser = new Parser();
 705   
 706  3 try
 707    {
 708  3 Node node = _conditionalExpressionParser.parse(expression);
 709   
 710  2 return node.evaluate(new EvaluationContextImpl(module.getClassResolver()));
 711    }
 712    catch (RuntimeException ex)
 713    {
 714  1 _errorHandler.error(_log, ex.getMessage(), location, ex);
 715   
 716  1 return false;
 717    }
 718    }
 719   
 720  1998 private static int size(Collection c)
 721    {
 722  1998 return c == null ? 0 : c.size();
 723    }
 724    }