You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@hivemind.apache.org by ah...@apache.org on 2006/10/17 16:26:51 UTC

svn commit: r464931 - in /hivemind/branches/branch-2-0-annot/framework/src/java/org/apache/hivemind: definition/ impl/

Author: ahuegen
Date: Tue Oct 17 07:26:48 2006
New Revision: 464931

URL: http://svn.apache.org/viewvc?view=rev&rev=464931
Log:
Introduced ExtensionResolver

Added:
    hivemind/branches/branch-2-0-annot/framework/src/java/org/apache/hivemind/impl/ExtensionResolver.java
Modified:
    hivemind/branches/branch-2-0-annot/framework/src/java/org/apache/hivemind/definition/DefinitionMessages.java
    hivemind/branches/branch-2-0-annot/framework/src/java/org/apache/hivemind/definition/RegistryDefinition.java
    hivemind/branches/branch-2-0-annot/framework/src/java/org/apache/hivemind/definition/UnresolvedExtension.java
    hivemind/branches/branch-2-0-annot/framework/src/java/org/apache/hivemind/impl/RegistryBuilder.java

Modified: hivemind/branches/branch-2-0-annot/framework/src/java/org/apache/hivemind/definition/DefinitionMessages.java
URL: http://svn.apache.org/viewvc/hivemind/branches/branch-2-0-annot/framework/src/java/org/apache/hivemind/definition/DefinitionMessages.java?view=diff&rev=464931&r1=464930&r2=464931
==============================================================================
--- hivemind/branches/branch-2-0-annot/framework/src/java/org/apache/hivemind/definition/DefinitionMessages.java (original)
+++ hivemind/branches/branch-2-0-annot/framework/src/java/org/apache/hivemind/definition/DefinitionMessages.java Tue Oct 17 07:26:48 2006
@@ -23,7 +23,7 @@
  * 
  * @author Achim Huegen
  */
-class DefinitionMessages
+public class DefinitionMessages
 {
     private static final MessageFormatter _formatter = new MessageFormatter(DefinitionMessages.class,
             "DefinitionStrings");
@@ -35,7 +35,7 @@
                 moduleId);
     }
 
-    static String wrongNumberOfContributions(ModuleDefinition definingModule, ConfigurationPointDefinition point, int actualCount,
+    public static String wrongNumberOfContributions(ModuleDefinition definingModule, ConfigurationPointDefinition point, int actualCount,
             Occurances expectation)
     {
         String fullyQualifiedId = IdUtils.qualify(definingModule.getId(), point.getId());
@@ -66,18 +66,18 @@
         return _formatter.getMessage("occurances." + occurances.getName());
     }
 
-    static String dependencyOnUnknownModule(String toModuleId)
+    public static String dependencyOnUnknownModule(String toModuleId)
     {
         return _formatter.format("dependency-on-unknown-module", toModuleId);
     }
     
-    static String unknownConfigurationPoint(String moduleId,
+    public static String unknownConfigurationPoint(String moduleId,
             String configurationId)
     {
         return _formatter.format("unknown-configuration-extension-point", moduleId, configurationId);
     }
 
-    static String unknownServicePoint(String moduleId, String pointId)
+    public static String unknownServicePoint(String moduleId, String pointId)
     {
         return _formatter.format(
                 "unknown-service-extension-point",
@@ -85,7 +85,7 @@
                 pointId);
     }
 
-    static String configurationPointNotVisible(ConfigurationPointDefinition point,
+    public static String configurationPointNotVisible(ConfigurationPointDefinition point,
             ModuleDefinition contributingModule)
     {
         return _formatter.format(

Modified: hivemind/branches/branch-2-0-annot/framework/src/java/org/apache/hivemind/definition/RegistryDefinition.java
URL: http://svn.apache.org/viewvc/hivemind/branches/branch-2-0-annot/framework/src/java/org/apache/hivemind/definition/RegistryDefinition.java?view=diff&rev=464931&r1=464930&r2=464931
==============================================================================
--- hivemind/branches/branch-2-0-annot/framework/src/java/org/apache/hivemind/definition/RegistryDefinition.java (original)
+++ hivemind/branches/branch-2-0-annot/framework/src/java/org/apache/hivemind/definition/RegistryDefinition.java Tue Oct 17 07:26:48 2006
@@ -3,19 +3,14 @@
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.HashMap;
-import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
 
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
 import org.apache.hivemind.ApplicationRuntimeException;
-import org.apache.hivemind.ErrorHandler;
-import org.apache.hivemind.Occurances;
 import org.apache.hivemind.events.RegistryInitializationListener;
-import org.apache.hivemind.impl.DefaultErrorHandler;
 import org.apache.hivemind.impl.RegistryPostProcessor;
-import org.apache.hivemind.internal.Visibility;
 import org.apache.hivemind.util.IdUtils;
 
 /**
@@ -30,8 +25,6 @@
 {
     private static final Log LOG = LogFactory.getLog(RegistryDefinition.class);
 
-    private ErrorHandler _errorHandler;
-
     private Map _modules = new HashMap();
 
     private Map _natures = new HashMap();
@@ -42,14 +35,8 @@
 
     public RegistryDefinition()
     {
-        this(new DefaultErrorHandler());
     }
     
-    public RegistryDefinition(ErrorHandler errorHandler)
-    {
-        _errorHandler = errorHandler;
-    }
-
     /**
      * Adds a module definition.
      * @param module  the module 
@@ -144,166 +131,6 @@
             configurationPoint = module.getConfigurationPoint(configurationPointId);
         }
         return configurationPoint;
-    }
-
-    /**
-     * Resolves all extensions, that couldn't be resolved before because the extension was added
-     * before the referenced extension point.
-     */
-    public void resolveExtensions()
-    {
-        for (Iterator iterModules = _modules.values().iterator(); iterModules.hasNext();)
-        {
-            ModuleDefinition module = (ModuleDefinition) iterModules.next();
-        
-            resolveImplementations(module);
-            resolveInterceptors(module);
-            resolveContributions(module);
-        }
-    }
-
-    private void resolveImplementations(ModuleDefinition module)
-    {
-        for (Iterator iter = module.getImplementations().iterator(); iter.hasNext();)
-        {
-            UnresolvedExtension unresolved = (UnresolvedExtension) iter.next();
-            String servicePointId = unresolved.getExtensionPointId();
-            ServicePointDefinition servicePoint = getServicePoint(servicePointId);
-            if (servicePoint == null)
-            {
-                _errorHandler.error(
-                        LOG,
-                        DefinitionMessages.unknownServicePoint(
-                                IdUtils.extractModule(servicePointId),
-                                IdUtils.stripModule(servicePointId)),
-                        unresolved.getExtension().getLocation(),
-                        null);
-            } else {
-                servicePoint.addImplementation((ServiceImplementationDefinition) unresolved.getExtension());
-            }
-
-        }
-    }
-    
-    private void resolveInterceptors(ModuleDefinition module)
-    {
-        for (Iterator iter = module.getInterceptors().iterator(); iter.hasNext();)
-        {
-            UnresolvedExtension unresolved = (UnresolvedExtension) iter.next();
-            String servicePointId = unresolved.getExtensionPointId();
-            ServicePointDefinition servicePoint = getServicePoint(servicePointId);
-            if (servicePoint == null)
-            {
-                _errorHandler.error(
-                        LOG,
-                        DefinitionMessages.unknownServicePoint(
-                                IdUtils.extractModule(servicePointId),
-                                IdUtils.stripModule(servicePointId)),
-                        unresolved.getExtension().getLocation(),
-                        null);
-            } else {
-                servicePoint.addInterceptor((ServiceInterceptorDefinition) unresolved.getExtension());
-            }
-
-        }
-    }
-    
-    private void resolveContributions(ModuleDefinition module)
-    {
-        for (Iterator iter = module.getContributions().iterator(); iter.hasNext();)
-        {
-            UnresolvedExtension unresolved = (UnresolvedExtension) iter.next();
-            String configurationPointId = unresolved.getExtensionPointId();
-            ConfigurationPointDefinition configurationPoint = getConfigurationPoint(configurationPointId);
-            if (configurationPoint == null)
-            {
-                _errorHandler.error(
-                        LOG,
-                        DefinitionMessages.unknownConfigurationPoint(
-                                IdUtils.extractModule(configurationPointId),
-                                IdUtils.stripModule(configurationPointId)),
-                        unresolved.getExtension().getLocation(),
-                        null);
-            } else {
-                if (Visibility.PRIVATE.equals(configurationPoint.getVisibility())
-                   && !module.getId().equals(IdUtils.extractModule(configurationPointId))) {
-                    // TODO: Ids are not qualified
-                    _errorHandler.error(
-                            LOG,
-                            DefinitionMessages.configurationPointNotVisible(
-                                    configurationPoint,
-                                    module),
-                            unresolved.getExtension().getLocation(),
-                            null);
-                    
-                }
-                
-                configurationPoint.addContribution((ContributionDefinition) unresolved.getExtension());
-            }
-
-        }
-    }
-
-    public void checkDependencies()
-    {
-        for (Iterator iterModules = _modules.values().iterator(); iterModules.hasNext();)
-        {
-            ModuleDefinition module = (ModuleDefinition) iterModules.next();
-            
-            for (Iterator iterDependencies = module.getDependencies().iterator(); iterDependencies.hasNext();)
-            {
-                String requiredModuleId = (String) iterDependencies.next();
-                checkModuleDependency(module, requiredModuleId);
-            }
-        }
-        
-    }
-
-    private void checkModuleDependency(ModuleDefinition sourceModule, String requiredModuleId)
-    {
-        ModuleDefinition requiredModule = (ModuleDefinition) _modules.get(requiredModuleId);
-        if (requiredModule == null)
-        {
-            // TODO annotation: Location in Dependencies aufnehmen
-            _errorHandler.error(
-                    LOG,
-                    DefinitionMessages.dependencyOnUnknownModule(requiredModuleId),
-                    null,
-                    null);
-            return;
-        }
-    }
-    
-    /**
-     * Checks that each configuration extension point has the right number of contributions.
-     */
-    public void checkContributionCounts()
-    {
-        for (Iterator iterModules = _modules.values().iterator(); iterModules.hasNext();)
-        {
-            ModuleDefinition module = (ModuleDefinition) iterModules.next();
-            
-            for (Iterator iterConfigurations = module.getConfigurationPoints().iterator(); iterConfigurations.hasNext();)
-            {
-                ConfigurationPointDefinition cpd = (ConfigurationPointDefinition) iterConfigurations.next();
-                checkContributionCounts(module, cpd);
-            }
-        }
-    }
-    
-    private void checkContributionCounts(ModuleDefinition definingModule, ConfigurationPointDefinition configurationPoint)
-    {
-        Occurances expected = configurationPoint.getExpectedContributions();
-
-        int actual = configurationPoint.getContributions().size();
-
-        if (expected.inRange(actual))
-            return;
-
-        _errorHandler.error(LOG, DefinitionMessages.wrongNumberOfContributions(
-                definingModule, configurationPoint,
-                actual,
-                expected), configurationPoint.getLocation(), null);
     }
 
 }

Modified: hivemind/branches/branch-2-0-annot/framework/src/java/org/apache/hivemind/definition/UnresolvedExtension.java
URL: http://svn.apache.org/viewvc/hivemind/branches/branch-2-0-annot/framework/src/java/org/apache/hivemind/definition/UnresolvedExtension.java?view=diff&rev=464931&r1=464930&r2=464931
==============================================================================
--- hivemind/branches/branch-2-0-annot/framework/src/java/org/apache/hivemind/definition/UnresolvedExtension.java (original)
+++ hivemind/branches/branch-2-0-annot/framework/src/java/org/apache/hivemind/definition/UnresolvedExtension.java Tue Oct 17 07:26:48 2006
@@ -1,7 +1,15 @@
 package org.apache.hivemind.definition;
 
-
-class UnresolvedExtension
+/**
+ * Represents an unresolved extension of an extension point in a registry definition. 
+ * For example a contribution to a configuration point. 
+ * An extension is regarded is unresolved if the corresponding definition is not directly
+ * added as object to the extension point definition but is associated by the fully
+ * qualified extension point id only. 
+ * 
+ * @author Achim Huegen
+ */
+public class UnresolvedExtension
 {
     private String _extensionPointId;
     private ExtensionDefinition _extension;

Added: hivemind/branches/branch-2-0-annot/framework/src/java/org/apache/hivemind/impl/ExtensionResolver.java
URL: http://svn.apache.org/viewvc/hivemind/branches/branch-2-0-annot/framework/src/java/org/apache/hivemind/impl/ExtensionResolver.java?view=auto&rev=464931
==============================================================================
--- hivemind/branches/branch-2-0-annot/framework/src/java/org/apache/hivemind/impl/ExtensionResolver.java (added)
+++ hivemind/branches/branch-2-0-annot/framework/src/java/org/apache/hivemind/impl/ExtensionResolver.java Tue Oct 17 07:26:48 2006
@@ -0,0 +1,170 @@
+package org.apache.hivemind.impl;
+
+import java.util.Iterator;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.hivemind.ErrorHandler;
+import org.apache.hivemind.Location;
+import org.apache.hivemind.definition.ConfigurationPointDefinition;
+import org.apache.hivemind.definition.ContributionDefinition;
+import org.apache.hivemind.definition.DefinitionMessages;
+import org.apache.hivemind.definition.ModuleDefinition;
+import org.apache.hivemind.definition.RegistryDefinition;
+import org.apache.hivemind.definition.ServiceImplementationDefinition;
+import org.apache.hivemind.definition.ServiceInterceptorDefinition;
+import org.apache.hivemind.definition.ServicePointDefinition;
+import org.apache.hivemind.definition.UnresolvedExtension;
+import org.apache.hivemind.internal.Visibility;
+import org.apache.hivemind.util.IdUtils;
+
+/**
+ * Resolves the {@link UnresolvedExtension unresolved extensions} in all
+ * modules of a {@link RegistryDefinition} during
+ * the construction of a registry by {@link RegistryBuilder}.
+ * Every unresolved extension (e.g. contribution, interceptor) references
+ * an extension point by its fully qualified id. This class looks for these
+ * extension points in the registry definition and adds the formerly unresolved
+ * extension directly to the extension points.
+ * The error handling is delegated to an instance of {@link ErrorHandler}.
+ * 
+ * @author Achim Huegen
+ */
+public class ExtensionResolver
+{
+    private static final Log LOG = LogFactory.getLog(ExtensionResolver.class);
+
+    private ErrorHandler _errorHandler;
+    
+    private RegistryDefinition _definition;
+
+    public ExtensionResolver(ErrorHandler errorHandler, RegistryDefinition definition)
+    {
+        _errorHandler = errorHandler;
+        _definition = definition;
+    }
+
+    /**
+     * Resolves all unresolved extensions in the registry definition passed in the constructor.
+     * During this process the object graph represented by the registry definition is changed, 
+     * so that afterwards it doesn't contain unresolved extensions any longer if anything went ok. 
+     * If errors occur it depends on the assigned {@link ErrorHandler} whether an exceptions
+     * is raised or errors are logged only. In the latter case all extensions that couldn't
+     * be resolved will remain in the module definitions.
+     */
+    public void resolveExtensions()
+    {
+        for (Iterator iterModules = _definition.getModules().iterator(); iterModules.hasNext();)
+        {
+            ModuleDefinition module = (ModuleDefinition) iterModules.next();
+        
+            resolveImplementations(module);
+            resolveInterceptors(module);
+            resolveContributions(module);
+        }
+    }
+
+    private void resolveImplementations(ModuleDefinition module)
+    {
+        for (Iterator iter = module.getImplementations().iterator(); iter.hasNext();)
+        {
+            UnresolvedExtension unresolved = (UnresolvedExtension) iter.next();
+            String servicePointId = unresolved.getExtensionPointId();
+            if (LOG.isDebugEnabled()) {
+                LOG.debug("Trying to resolve service point " + servicePointId + " referenced by" +
+                        " implementation" + logLocation(unresolved.getExtension().getLocation()));
+            }
+            ServicePointDefinition servicePoint = _definition.getServicePoint(servicePointId);
+            if (servicePoint == null)
+            {
+                _errorHandler.error(
+                        LOG,
+                        DefinitionMessages.unknownServicePoint(
+                                IdUtils.extractModule(servicePointId),
+                                IdUtils.stripModule(servicePointId)),
+                        unresolved.getExtension().getLocation(),
+                        null);
+            } else {
+                servicePoint.addImplementation((ServiceImplementationDefinition) unresolved.getExtension());
+            }
+            iter.remove();
+        }
+    }
+    
+    private String logLocation(Location location)
+    {
+        if (location == null) {
+            return "";
+        } else {
+            return " at " + location.toString();
+        }
+    }
+    
+    private void resolveInterceptors(ModuleDefinition module)
+    {
+        for (Iterator iter = module.getInterceptors().iterator(); iter.hasNext();)
+        {
+            UnresolvedExtension unresolved = (UnresolvedExtension) iter.next();
+            String servicePointId = unresolved.getExtensionPointId();
+            if (LOG.isDebugEnabled()) {
+                LOG.debug("Trying to resolve service point " + servicePointId + " referenced by" +
+                        " interceptor" + logLocation(unresolved.getExtension().getLocation()));
+            }
+            ServicePointDefinition servicePoint = _definition.getServicePoint(servicePointId);
+            if (servicePoint == null)
+            {
+                _errorHandler.error(
+                        LOG,
+                        DefinitionMessages.unknownServicePoint(
+                                IdUtils.extractModule(servicePointId),
+                                IdUtils.stripModule(servicePointId)),
+                        unresolved.getExtension().getLocation(),
+                        null);
+            } else {
+                servicePoint.addInterceptor((ServiceInterceptorDefinition) unresolved.getExtension());
+            }
+            iter.remove();
+        }
+    }
+    
+    private void resolveContributions(ModuleDefinition module)
+    {
+        for (Iterator iter = module.getContributions().iterator(); iter.hasNext();)
+        {
+            UnresolvedExtension unresolved = (UnresolvedExtension) iter.next();
+            String configurationPointId = unresolved.getExtensionPointId();
+            if (LOG.isDebugEnabled()) {
+                LOG.debug("Trying to resolve configuration point " + configurationPointId + " referenced by" +
+                        " contribution " + logLocation(unresolved.getExtension().getLocation()));
+            }
+            ConfigurationPointDefinition configurationPoint = _definition.getConfigurationPoint(configurationPointId);
+            if (configurationPoint == null)
+            {
+                _errorHandler.error(
+                        LOG,
+                        DefinitionMessages.unknownConfigurationPoint(
+                                IdUtils.extractModule(configurationPointId),
+                                IdUtils.stripModule(configurationPointId)),
+                        unresolved.getExtension().getLocation(),
+                        null);
+            } else {
+                if (Visibility.PRIVATE.equals(configurationPoint.getVisibility())
+                   && !module.getId().equals(IdUtils.extractModule(configurationPointId))) {
+                    // TODO: Ids are not qualified
+                    _errorHandler.error(
+                            LOG,
+                            DefinitionMessages.configurationPointNotVisible(
+                                    configurationPoint,
+                                    module),
+                            unresolved.getExtension().getLocation(),
+                            null);
+                    
+                }
+                
+                configurationPoint.addContribution((ContributionDefinition) unresolved.getExtension());
+            }
+            iter.remove();
+        }
+    }
+
+}

Modified: hivemind/branches/branch-2-0-annot/framework/src/java/org/apache/hivemind/impl/RegistryBuilder.java
URL: http://svn.apache.org/viewvc/hivemind/branches/branch-2-0-annot/framework/src/java/org/apache/hivemind/impl/RegistryBuilder.java?view=diff&rev=464931&r1=464930&r2=464931
==============================================================================
--- hivemind/branches/branch-2-0-annot/framework/src/java/org/apache/hivemind/impl/RegistryBuilder.java (original)
+++ hivemind/branches/branch-2-0-annot/framework/src/java/org/apache/hivemind/impl/RegistryBuilder.java Tue Oct 17 07:26:48 2006
@@ -21,7 +21,11 @@
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
 import org.apache.hivemind.ErrorHandler;
+import org.apache.hivemind.Occurances;
 import org.apache.hivemind.Registry;
+import org.apache.hivemind.definition.ConfigurationPointDefinition;
+import org.apache.hivemind.definition.DefinitionMessages;
+import org.apache.hivemind.definition.ModuleDefinition;
 import org.apache.hivemind.definition.RegistryDefinition;
 import org.apache.hivemind.events.RegistryInitializationListener;
 import org.apache.hivemind.internal.RegistryInfrastructure;
@@ -82,16 +86,27 @@
     {
         this(new DefaultErrorHandler());
     }
+    
+    public RegistryBuilder(RegistryDefinition registryDefinition)
+    {
+        this(registryDefinition, new DefaultErrorHandler());
+    }
 
     public RegistryBuilder(ErrorHandler handler)
     {
         _errorHandler = handler;
     }
+    
+    public RegistryBuilder(RegistryDefinition registryDefinition, ErrorHandler handler)
+    {
+        _registryDefinition = registryDefinition;
+        _errorHandler = handler;
+    }
 
     public RegistryDefinition getRegistryDefinition()
     {
         if (_registryDefinition == null) {
-            _registryDefinition = new RegistryDefinition(_errorHandler);
+            _registryDefinition = new RegistryDefinition();
         }
         return _registryDefinition;
     }
@@ -103,24 +118,32 @@
     public Registry constructRegistry(Locale locale)
     {
         RegistryDefinition definition = getRegistryDefinition();
-        
+        return constructRegistry(definition, _errorHandler, locale);
+    }
+    
+    public Registry constructRegistry(RegistryDefinition definition, ErrorHandler errorHandler,
+            Locale locale)
+    {
         // Add Core HiveMind services like ClassFactory
         CoreServicesProvider coreServicesProvider = new CoreServicesProvider();
-        coreServicesProvider.process(definition, _errorHandler);
+        coreServicesProvider.process(definition, errorHandler);
+        
+        // Try to resolve all so far unresolved extensions
+        ExtensionResolver extensionResolver = new ExtensionResolver(errorHandler, definition);
+        extensionResolver.resolveExtensions();
         
-        definition.resolveExtensions();
-        definition.checkDependencies();
-        definition.checkContributionCounts();
+        checkDependencies(definition);
+        checkContributionCounts(definition);
         
         // Notify post processors
         for (Iterator i = definition.getPostProcessors().iterator(); i.hasNext();)
         {
             RegistryPostProcessor processor = (RegistryPostProcessor) i.next();
 
-            processor.postprocess(definition, _errorHandler);
+            processor.postprocess(definition, errorHandler);
         }
 
-        RegistryInfrastructureConstructor constructor = new RegistryInfrastructureConstructor(_errorHandler, LOG, locale);
+        RegistryInfrastructureConstructor constructor = new RegistryInfrastructureConstructor(errorHandler, LOG, locale);
         RegistryInfrastructure infrastructure = constructor
                 .constructRegistryInfrastructure(definition);
 
@@ -135,6 +158,68 @@
         infrastructure.startup();
 
         return new RegistryImpl(infrastructure);
+    }
+
+    private void checkDependencies(RegistryDefinition definition)
+    {
+        for (Iterator iterModules = definition.getModules().iterator(); iterModules.hasNext();)
+        {
+            ModuleDefinition module = (ModuleDefinition) iterModules.next();
+            
+            for (Iterator iterDependencies = module.getDependencies().iterator(); iterDependencies.hasNext();)
+            {
+                String requiredModuleId = (String) iterDependencies.next();
+                checkModuleDependency(definition, module, requiredModuleId);
+            }
+        }
+        
+    }
+
+    private void checkModuleDependency(RegistryDefinition definition, ModuleDefinition sourceModule, String requiredModuleId)
+    {
+        ModuleDefinition requiredModule = (ModuleDefinition) definition.getModule(requiredModuleId);
+        if (requiredModule == null)
+        {
+            // TODO annotation: Location in Dependencies aufnehmen
+            _errorHandler.error(
+                    LOG,
+                    DefinitionMessages.dependencyOnUnknownModule(requiredModuleId),
+                    null,
+                    null);
+            return;
+        }
+    }
+    
+    /**
+     * Checks that each configuration extension point has the right number of contributions.
+     */
+    public void checkContributionCounts(RegistryDefinition definition)
+    {
+        for (Iterator iterModules = definition.getModules().iterator(); iterModules.hasNext();)
+        {
+            ModuleDefinition module = (ModuleDefinition) iterModules.next();
+            
+            for (Iterator iterConfigurations = module.getConfigurationPoints().iterator(); iterConfigurations.hasNext();)
+            {
+                ConfigurationPointDefinition cpd = (ConfigurationPointDefinition) iterConfigurations.next();
+                checkContributionCounts(module, cpd);
+            }
+        }
+    }
+    
+    private void checkContributionCounts(ModuleDefinition definingModule, ConfigurationPointDefinition configurationPoint)
+    {
+        Occurances expected = configurationPoint.getExpectedContributions();
+
+        int actual = configurationPoint.getContributions().size();
+
+        if (expected.inRange(actual))
+            return;
+
+        _errorHandler.error(LOG, DefinitionMessages.wrongNumberOfContributions(
+                definingModule, configurationPoint,
+                actual,
+                expected), configurationPoint.getLocation(), null);
     }
 
     public void autoDetectModules()