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: 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  128 public RegistryInfrastructureConstructor(ErrorHandler errorHandler, Log log,
 71    RegistryAssembly assembly)
 72    {
 73  128 _errorHandler = errorHandler;
 74  128 _log = log;
 75  128 _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  128 public RegistryInfrastructure constructRegistryInfrastructure(Locale locale)
 171    {
 172  128 RegistryInfrastructureImpl result = new RegistryInfrastructureImpl(_errorHandler, locale);
 173   
 174  128 addServiceAndConfigurationPoints(result);
 175   
 176  128 addImplementationsAndContributions();
 177   
 178  128 checkForMissingServices();
 179   
 180  128 checkContributionCounts();
 181   
 182  128 result.setShutdownCoordinator(_shutdownCoordinator);
 183   
 184  128 addModulesToRegistry(result);
 185   
 186    // The caller is responsible for invoking startup().
 187   
 188  128 return result;
 189    }
 190   
 191  256 public void addModuleDescriptor(ModuleDescriptor md)
 192    {
 193  256 String id = md.getModuleId();
 194   
 195  256 if (_log.isDebugEnabled())
 196  28 _log.debug("Processing module " + id);
 197   
 198  256 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  255 ModuleImpl module = new ModuleImpl();
 210   
 211  255 module.setLocation(md.getLocation());
 212  255 module.setModuleId(id);
 213  255 module.setPackageName(md.getPackageName());
 214  255 module.setClassResolver(md.getClassResolver());
 215   
 216  255 if (size(md.getDependencies()) > 0)
 217  3 _assembly.addPostProcessor(new ModuleDependencyChecker(md));
 218   
 219  255 for (Iterator schemas = md.getSchemas().iterator(); schemas.hasNext();)
 220    {
 221  293 SchemaImpl schema = (SchemaImpl) schemas.next();
 222   
 223  293 schema.setModule(module);
 224   
 225  293 _schemas.put(IdUtils.qualify(id, schema.getId()), schema);
 226    }
 227   
 228  255 _modules.put(id, module);
 229   
 230  255 _moduleDescriptors.put(id, md);
 231    }
 232   
 233  128 private void addServiceAndConfigurationPoints(RegistryInfrastructureImpl infrastructure)
 234    {
 235  128 for (Iterator i = _moduleDescriptors.values().iterator(); i.hasNext();)
 236    {
 237  255 ModuleDescriptor md = (ModuleDescriptor) i.next();
 238   
 239  255 String id = md.getModuleId();
 240   
 241  255 ModuleImpl module = (ModuleImpl) _modules.get(id);
 242   
 243  255 addServicePoints(infrastructure, module, md);
 244   
 245  255 addConfigurationPoints(infrastructure, module, md);
 246    }
 247    }
 248   
 249  255 private void addServicePoints(RegistryInfrastructureImpl infrastructure, Module module,
 250    ModuleDescriptor md)
 251    {
 252  255 String moduleId = md.getModuleId();
 253  255 List services = md.getServicePoints();
 254  255 int count = size(services);
 255   
 256  255 for (int i = 0; i < count; i++)
 257    {
 258  2546 ServicePointDescriptor sd = (ServicePointDescriptor) services.get(i);
 259   
 260  2546 String pointId = moduleId + "." + sd.getId();
 261   
 262  2546 ServicePoint existingPoint = (ServicePoint) _servicePoints.get(pointId);
 263   
 264  2546 if (existingPoint != null)
 265    {
 266  1 _errorHandler.error(_log, ImplMessages.duplicateExtensionPointId(
 267    pointId,
 268    existingPoint), sd.getLocation(), null);
 269  1 continue;
 270    }
 271   
 272  2545 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  2545 ServicePointImpl point = new ServicePointImpl();
 280   
 281  2545 point.setExtensionPointId(pointId);
 282  2545 point.setLocation(sd.getLocation());
 283  2545 point.setModule(module);
 284   
 285  2545 point.setServiceInterfaceName(sd.getInterfaceClassName());
 286   
 287  2545 point.setParametersSchema(findSchema(sd.getParametersSchema(), module, sd
 288    .getParametersSchemaId(), point.getLocation()));
 289   
 290  2545 point.setParametersCount(sd.getParametersCount());
 291  2545 point.setVisibility(sd.getVisibility());
 292   
 293  2545 point.setShutdownCoordinator(_shutdownCoordinator);
 294   
 295  2545 infrastructure.addServicePoint(point);
 296   
 297    // Save this for the second phase, where contributions
 298    // from other modules are applied.
 299   
 300  2545 _servicePoints.put(pointId, point);
 301   
 302  2545 addInternalImplementations(module, pointId, sd);
 303    }
 304    }
 305   
 306  255 private void addConfigurationPoints(RegistryInfrastructureImpl registry, Module module,
 307    ModuleDescriptor md)
 308    {
 309  255 String moduleId = md.getModuleId();
 310  255 List points = md.getConfigurationPoints();
 311  255 int count = size(points);
 312   
 313  255 for (int i = 0; i < count; i++)
 314    {
 315  1030 ConfigurationPointDescriptor cpd = (ConfigurationPointDescriptor) points.get(i);
 316   
 317  1030 String pointId = moduleId + "." + cpd.getId();
 318   
 319  1030 ConfigurationPoint existingPoint = (ConfigurationPoint) _configurationPoints
 320    .get(pointId);
 321   
 322  1030 if (existingPoint != null)
 323    {
 324  1 _errorHandler.error(_log, ImplMessages.duplicateExtensionPointId(
 325    pointId,
 326    existingPoint), cpd.getLocation(), null);
 327  1 continue;
 328    }
 329   
 330  1029 if (_log.isDebugEnabled())
 331  112 _log.debug("Creating configuration point " + pointId);
 332   
 333  1029 ConfigurationPointImpl point = new ConfigurationPointImpl();
 334   
 335  1029 point.setExtensionPointId(pointId);
 336  1029 point.setLocation(cpd.getLocation());
 337  1029 point.setModule(module);
 338  1029 point.setExpectedCount(cpd.getCount());
 339   
 340  1029 point.setContributionsSchema(findSchema(cpd.getContributionsSchema(), module, cpd
 341    .getContributionsSchemaId(), cpd.getLocation()));
 342   
 343  1029 point.setVisibility(cpd.getVisibility());
 344   
 345  1029 point.setShutdownCoordinator(_shutdownCoordinator);
 346   
 347  1029 registry.addConfigurationPoint(point);
 348   
 349    // Needed later when we reconcile the rest
 350    // of the configuration contributions.
 351   
 352  1029 _configurationPoints.put(pointId, point);
 353    }
 354    }
 355   
 356  673 private void addContributionElements(Module sourceModule, ConfigurationPointImpl point,
 357    List elements)
 358    {
 359  673 if (size(elements) == 0)
 360  0 return;
 361   
 362  673 if (_log.isDebugEnabled())
 363  73 _log
 364    .debug("Adding contributions to configuration point "
 365    + point.getExtensionPointId());
 366   
 367  673 ContributionImpl c = new ContributionImpl();
 368  673 c.setContributingModule(sourceModule);
 369  673 c.addElements(elements);
 370   
 371  673 point.addContribution(c);
 372    }
 373   
 374  128 private void addModulesToRegistry(RegistryInfrastructureImpl registry)
 375    {
 376    // Add each module to the registry.
 377   
 378  128 Iterator i = _modules.values().iterator();
 379  128 while (i.hasNext())
 380    {
 381  255 ModuleImpl module = (ModuleImpl) i.next();
 382   
 383  255 if (_log.isDebugEnabled())
 384  27 _log.debug("Adding module " + module.getModuleId() + " to registry");
 385   
 386  255 module.setRegistry(registry);
 387    }
 388    }
 389   
 390  128 private void addImplementationsAndContributions()
 391    {
 392  128 for (Iterator i = _moduleDescriptors.values().iterator(); i.hasNext();)
 393    {
 394  255 ModuleDescriptor md = (ModuleDescriptor) i.next();
 395   
 396  255 if (_log.isDebugEnabled())
 397  27 _log.debug("Adding contributions from module " + md.getModuleId());
 398   
 399  255 addImplementations(md);
 400  255 addContributions(md);
 401    }
 402    }
 403   
 404  255 private void addImplementations(ModuleDescriptor md)
 405    {
 406  255 String moduleId = md.getModuleId();
 407  255 Module sourceModule = (Module) _modules.get(moduleId);
 408   
 409  255 List implementations = md.getImplementations();
 410  255 int count = size(implementations);
 411   
 412  255 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  255 private void addContributions(ModuleDescriptor md)
 429    {
 430  255 String moduleId = md.getModuleId();
 431  255 Module sourceModule = (Module) _modules.get(moduleId);
 432   
 433  255 List contributions = md.getContributions();
 434  255 int count = size(contributions);
 435   
 436  255 for (int i = 0; i < count; i++)
 437    {
 438  677 ContributionDescriptor cd = (ContributionDescriptor) contributions.get(i);
 439   
 440  677 if (!includeContribution(cd.getConditionalExpression(), sourceModule, cd.getLocation()))
 441  2 continue;
 442   
 443  675 String pointId = cd.getConfigurationId();
 444  675 String qualifiedId = IdUtils.qualify(moduleId, pointId);
 445   
 446  675 ConfigurationPointImpl point = (ConfigurationPointImpl) _configurationPoints
 447    .get(qualifiedId);
 448   
 449  675 if (point == null)
 450    {
 451  1 _errorHandler.error(_log, ImplMessages.unknownConfigurationPoint(moduleId, cd), cd
 452    .getLocation(), null);
 453   
 454  1 continue;
 455    }
 456   
 457  674 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  673 addContributionElements(sourceModule, point, cd.getElements());
 466    }
 467    }
 468   
 469  3574 private Schema findSchema(SchemaImpl schema, Module module, String schemaId, Location location)
 470    {
 471  3574 if (schema != null)
 472    {
 473  851 schema.setModule(module);
 474  851 return schema;
 475    }
 476   
 477  2723 if (schemaId == null)
 478  2308 return null;
 479   
 480  415 String moduleId = module.getModuleId();
 481  415 String qualifiedId = IdUtils.qualify(moduleId, schemaId);
 482   
 483  415 return getSchema(qualifiedId, moduleId, location);
 484    }
 485   
 486  415 private Schema getSchema(String schemaId, String referencingModule, Location reference)
 487    {
 488  415 Schema schema = (Schema) _schemas.get(schemaId);
 489   
 490  415 if (schema == null)
 491  1 _errorHandler
 492    .error(_log, ImplMessages.unableToResolveSchema(schemaId), reference, null);
 493  414 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  415 return schema;
 504    }
 505   
 506    /**
 507    * Adds internal service contributions; the contributions provided inplace with the service
 508    * definition.
 509    */
 510  2545 private void addInternalImplementations(Module sourceModule, String pointId,
 511    ServicePointDescriptor spd)
 512    {
 513  2545 InstanceBuilder builder = spd.getInstanceBuilder();
 514  2545 List interceptors = spd.getInterceptors();
 515   
 516  2545 if (builder == null && interceptors == null)
 517  4 return;
 518   
 519  2541 if (builder != null)
 520  2541 addServiceInstanceBuilder(sourceModule, pointId, builder, true);
 521   
 522  2541 if (interceptors == null)
 523  2514 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  2543 private void addServiceInstanceBuilder(Module sourceModule, String pointId,
 559    InstanceBuilder builder, boolean isDefault)
 560    {
 561  2543 if (_log.isDebugEnabled())
 562  247 _log.debug("Adding " + builder + " to service extension point " + pointId);
 563   
 564  2543 ServicePointImpl point = (ServicePointImpl) _servicePoints.get(pointId);
 565   
 566  2543 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  2543 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  2542 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  2542 point.setServiceModel(builder.getServiceModel());
 598  2542 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  128 private void checkForMissingServices()
 646    {
 647  128 Iterator i = _servicePoints.values().iterator();
 648  128 while (i.hasNext())
 649    {
 650  2545 ServicePointImpl point = (ServicePointImpl) i.next();
 651   
 652  2545 if (point.getServiceConstructor() != null)
 653  2542 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  128 private void checkContributionCounts()
 664    {
 665  128 Iterator i = _configurationPoints.values().iterator();
 666   
 667  128 while (i.hasNext())
 668    {
 669  1029 ConfigurationPointImpl point = (ConfigurationPointImpl) i.next();
 670   
 671  1029 Occurances expected = point.getExpectedCount();
 672   
 673  1029 int actual = point.getContributionCount();
 674   
 675  1029 if (expected.inRange(actual))
 676  1027 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  681 private boolean includeContribution(String expression, Module module, Location location)
 699    {
 700  681 if (expression == null)
 701  678 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  1982 private static int size(Collection c)
 721    {
 722  1982 return c == null ? 0 : c.size();
 723    }
 724    }