[jboss-cvs] JBossAS SVN: r75592 - in projects/jboss-cl/trunk: classloading and 11 other directories.

jboss-cvs-commits at lists.jboss.org jboss-cvs-commits at lists.jboss.org
Thu Jul 10 05:55:13 EDT 2008


Author: adrian at jboss.org
Date: 2008-07-10 05:55:12 -0400 (Thu, 10 Jul 2008)
New Revision: 75592

Added:
   projects/jboss-cl/trunk/classloading/src/main/org/jboss/classloading/spi/dependency/ClassLoadingSpace.java
   projects/jboss-cl/trunk/classloading/src/main/org/jboss/classloading/spi/metadata/OptionalPackages.java
   projects/jboss-cl/trunk/classloading/src/tests/org/jboss/test/classloading/dependency/test/ConflictingPackageUnitTestCase.java
   projects/jboss-cl/trunk/classloading/src/tests/org/jboss/test/classloading/dependency/test/ConflictingRequirementUnitTestCase.java
   projects/jboss-cl/trunk/classloading/src/tests/org/jboss/test/classloading/dependency/test/HierarchicalDomainUnitTestCase.java
Modified:
   projects/jboss-cl/trunk/build/pom.xml
   projects/jboss-cl/trunk/classloading/.classpath
   projects/jboss-cl/trunk/classloading/src/main/org/jboss/classloading/plugins/metadata/ModuleCapability.java
   projects/jboss-cl/trunk/classloading/src/main/org/jboss/classloading/plugins/metadata/PackageRequirement.java
   projects/jboss-cl/trunk/classloading/src/main/org/jboss/classloading/spi/dependency/ClassLoading.java
   projects/jboss-cl/trunk/classloading/src/main/org/jboss/classloading/spi/dependency/Domain.java
   projects/jboss-cl/trunk/classloading/src/main/org/jboss/classloading/spi/dependency/Module.java
   projects/jboss-cl/trunk/classloading/src/main/org/jboss/classloading/spi/dependency/RequirementDependencyItem.java
   projects/jboss-cl/trunk/classloading/src/main/org/jboss/classloading/spi/dependency/helpers/ClassLoadingMetaDataModule.java
   projects/jboss-cl/trunk/classloading/src/main/org/jboss/classloading/spi/dependency/policy/ClassLoaderPolicyModule.java
   projects/jboss-cl/trunk/classloading/src/main/org/jboss/classloading/spi/metadata/Requirement.java
   projects/jboss-cl/trunk/classloading/src/main/org/jboss/classloading/spi/metadata/helpers/AbstractRequirement.java
   projects/jboss-cl/trunk/classloading/src/main/org/jboss/classloading/spi/version/VersionRange.java
   projects/jboss-cl/trunk/classloading/src/tests/org/jboss/test/classloading/dependency/DependencyTestSuite.java
   projects/jboss-cl/trunk/classloading/src/tests/org/jboss/test/classloading/dependency/test/AbstractMockClassLoaderUnitTest.java
   projects/jboss-cl/trunk/classloading/src/tests/org/jboss/test/classloading/metadata/test/ModuleRequirementUnitTestCase.java
   projects/jboss-cl/trunk/classloading/src/tests/org/jboss/test/classloading/metadata/test/PackageRequirementUnitTestCase.java
   projects/jboss-cl/trunk/classloading/src/tests/org/jboss/test/classloading/version/test/VersionRangeUnitTestCase.java
Log:
[JBCL-7] - Majority of the features, but still some work to do

Modified: projects/jboss-cl/trunk/build/pom.xml
===================================================================
--- projects/jboss-cl/trunk/build/pom.xml	2008-07-10 09:41:53 UTC (rev 75591)
+++ projects/jboss-cl/trunk/build/pom.xml	2008-07-10 09:55:12 UTC (rev 75592)
@@ -22,7 +22,7 @@
 
   <properties>
     <version.jboss.man>2.0.0.Beta12</version.jboss.man>
-    <version.jboss.microcontainer>2.0.0.Beta14</version.jboss.microcontainer>
+    <version.jboss.microcontainer>2.0.0-SNAPSHOT</version.jboss.microcontainer>
     <version.jboss.common.core>2.2.5.GA</version.jboss.common.core>
     <version.jboss.logging.spi>2.0.5.GA</version.jboss.logging.spi>
     <version.jboss.classloading.spi>5.0.0.Beta4</version.jboss.classloading.spi>
@@ -280,4 +280,4 @@
       </properties>
     </profile>
   </profiles>
-</project>
\ No newline at end of file
+</project>

Modified: projects/jboss-cl/trunk/classloading/.classpath
===================================================================
--- projects/jboss-cl/trunk/classloading/.classpath	2008-07-10 09:41:53 UTC (rev 75591)
+++ projects/jboss-cl/trunk/classloading/.classpath	2008-07-10 09:55:12 UTC (rev 75592)
@@ -10,7 +10,7 @@
   <classpathentry kind="src" path="/jboss-classloader"/>
   <classpathentry kind="var" path="M2_REPO/org/jboss/jboss-classloading-spi/5.0.0.Beta4/jboss-classloading-spi-5.0.0.Beta4.jar" sourcepath="M2_REPO/org/jboss/jboss-classloading-spi/5.0.0.Beta4/jboss-classloading-spi-5.0.0.Beta4-sources.jar"/>
   <classpathentry kind="var" path="M2_REPO/org/jboss/jboss-common-core/2.2.5.GA/jboss-common-core-2.2.5.GA.jar" sourcepath="M2_REPO/org/jboss/jboss-common-core/2.2.5.GA/jboss-common-core-2.2.5.GA-sources.jar"/>
-  <classpathentry kind="var" path="M2_REPO/org/jboss/microcontainer/jboss-dependency/2.0.0.Beta14/jboss-dependency-2.0.0.Beta14.jar" sourcepath="M2_REPO/org/jboss/microcontainer/jboss-dependency/2.0.0.Beta14/jboss-dependency-2.0.0.Beta14-sources.jar"/>
+  <classpathentry kind="var" path="M2_REPO/org/jboss/microcontainer/jboss-dependency/2.0.0-SNAPSHOT/jboss-dependency-2.0.0-SNAPSHOT.jar" sourcepath="M2_REPO/org/jboss/microcontainer/jboss-dependency/2.0.0-SNAPSHOT/jboss-dependency-2.0.0-SNAPSHOT-sources.jar"/>
   <classpathentry kind="var" path="M2_REPO/org/jboss/microcontainer/jboss-kernel/2.0.0.Beta14/jboss-kernel-2.0.0.Beta14.jar" sourcepath="M2_REPO/org/jboss/microcontainer/jboss-kernel/2.0.0.Beta14/jboss-kernel-2.0.0.Beta14-sources.jar"/>
   <classpathentry kind="var" path="M2_REPO/org/jboss/logging/jboss-logging-log4j/2.0.5.GA/jboss-logging-log4j-2.0.5.GA.jar" sourcepath="M2_REPO/org/jboss/logging/jboss-logging-log4j/2.0.5.GA/jboss-logging-log4j-2.0.5.GA-sources.jar"/>
   <classpathentry kind="var" path="M2_REPO/org/jboss/logging/jboss-logging-spi/2.0.5.GA/jboss-logging-spi-2.0.5.GA.jar" sourcepath="M2_REPO/org/jboss/logging/jboss-logging-spi/2.0.5.GA/jboss-logging-spi-2.0.5.GA-sources.jar"/>

Modified: projects/jboss-cl/trunk/classloading/src/main/org/jboss/classloading/plugins/metadata/ModuleCapability.java
===================================================================
--- projects/jboss-cl/trunk/classloading/src/main/org/jboss/classloading/plugins/metadata/ModuleCapability.java	2008-07-10 09:41:53 UTC (rev 75591)
+++ projects/jboss-cl/trunk/classloading/src/main/org/jboss/classloading/plugins/metadata/ModuleCapability.java	2008-07-10 09:55:12 UTC (rev 75592)
@@ -22,7 +22,6 @@
 package org.jboss.classloading.plugins.metadata;
 
 import org.jboss.classloading.spi.dependency.Module;
-import org.jboss.classloading.spi.metadata.Capability;
 import org.jboss.classloading.spi.metadata.Requirement;
 import org.jboss.classloading.spi.metadata.helpers.AbstractCapability;
 
@@ -32,7 +31,7 @@
  * @author <a href="adrian at jboss.com">Adrian Brock</a>
  * @version $Revision: 1.1 $
  */
-public class ModuleCapability extends AbstractCapability implements Capability
+public class ModuleCapability extends AbstractCapability
 {
    /** The serialVersionUID */
    private static final long serialVersionUID = -5444212755644141118L;

Modified: projects/jboss-cl/trunk/classloading/src/main/org/jboss/classloading/plugins/metadata/PackageRequirement.java
===================================================================
--- projects/jboss-cl/trunk/classloading/src/main/org/jboss/classloading/plugins/metadata/PackageRequirement.java	2008-07-10 09:41:53 UTC (rev 75591)
+++ projects/jboss-cl/trunk/classloading/src/main/org/jboss/classloading/plugins/metadata/PackageRequirement.java	2008-07-10 09:55:12 UTC (rev 75592)
@@ -21,6 +21,12 @@
 */
 package org.jboss.classloading.plugins.metadata;
 
+import java.util.Collections;
+import java.util.Set;
+
+import org.jboss.classloading.spi.dependency.Module;
+import org.jboss.classloading.spi.metadata.OptionalPackages;
+import org.jboss.classloading.spi.metadata.Requirement;
 import org.jboss.classloading.spi.metadata.helpers.AbstractRequirement;
 import org.jboss.classloading.spi.version.VersionRange;
 
@@ -30,7 +36,7 @@
  * @author <a href="adrian at jboss.com">Adrian Brock</a>
  * @version $Revision: 1.1 $
  */
-public class PackageRequirement extends AbstractRequirement
+public class PackageRequirement extends AbstractRequirement implements OptionalPackages
 {
    /** The serialVersionUID */
    private static final long serialVersionUID = -7552921085464308835L;
@@ -65,7 +71,20 @@
       super(name, versionRange);
    }
    
+   public Set<String> getOptionalPackageNames(Module module)
+   {
+      if (isOptional() == false)
+         return null;
+      return Collections.singleton(getName());
+   }
+
    @Override
+   public boolean isConsistent(Requirement other)
+   {
+      return isConsistent(other, PackageRequirement.class);
+   }
+
+   @Override
    public boolean equals(Object obj)
    {
       if (obj == this)

Modified: projects/jboss-cl/trunk/classloading/src/main/org/jboss/classloading/spi/dependency/ClassLoading.java
===================================================================
--- projects/jboss-cl/trunk/classloading/src/main/org/jboss/classloading/spi/dependency/ClassLoading.java	2008-07-10 09:41:53 UTC (rev 75591)
+++ projects/jboss-cl/trunk/classloading/src/main/org/jboss/classloading/spi/dependency/ClassLoading.java	2008-07-10 09:55:12 UTC (rev 75592)
@@ -28,12 +28,15 @@
 
 /**
  * ClassLoading.
- * 
+ *
  * @author <a href="adrian at jboss.org">Adrian Brock</a>
  * @version $Revision: 1.1 $
  */
 public class ClassLoading
 {
+   /** An empty default domain */
+   private Domain EMPTY_DOMAIN = new Domain(this, ClassLoaderSystem.DEFAULT_DOMAIN_NAME, null, true);
+   
    /** The classloading domains by name */
    private Map<String, Domain> domains = new ConcurrentHashMap<String, Domain>();
    
@@ -49,20 +52,9 @@
          throw new IllegalArgumentException("Null module");
       
       String domainName = module.getDeterminedDomainName();
-      if (domainName == null)
-         domainName = ClassLoaderSystem.DEFAULT_DOMAIN_NAME;
-      
-      Domain domain;
-      synchronized (domains)
-      {
-         domain = domains.get(domainName);
-         if (domain == null)
-         {
-            domain = new Domain(domainName);
-            domains.put(domainName, domain);
-         }
-      }
-      
+      boolean parentFirst = module.isJ2seClassLoadingCompliance();
+      String parentDomainName = module.getDeterminedParentDomainName();
+      Domain domain = getDomain(domainName, parentDomainName, parentFirst);
       domain.addModule(module);
    }
    
@@ -78,4 +70,63 @@
          throw new IllegalArgumentException("Null module");
       module.release();
    }
+
+   /**
+    * Get or create the domain
+    * 
+    * @param domainName the domain name
+    * @param parentDomainName the parent domain name
+    * @param parentFirst whether to look in the parent first
+    * @return the domain
+    * @throws IllegalArgumentException for a null domain
+    */
+   protected Domain getDomain(String domainName, String parentDomainName, boolean parentFirst)
+   {
+      Domain domain;
+      synchronized (domains)
+      {
+         domain = getDomain(domainName);
+         if (domain == null)
+         {
+            domain = createDomain(domainName, parentDomainName, parentFirst);
+            domains.put(domainName, domain);
+         }
+      }
+      return domain;
+   }
+
+   /**
+    * Get a domain
+    * 
+    * @param domainName the domain name
+    * @return the domain or null if it doesn't exist
+    */
+   protected Domain getDomain(String domainName)
+   {
+      if (domainName == null)
+         throw new IllegalArgumentException("Null domain name");
+
+      Domain domain = domains.get(domainName);
+      // This is hack, but it is a situation that probably only occurs in the tests
+      // i.e. there are no classloaders in the default domain so it doesn't exist
+      if (domain == null && ClassLoaderSystem.DEFAULT_DOMAIN_NAME.equals(domainName))
+         domain = EMPTY_DOMAIN;
+      return domain;
+   }
+   
+   /**
+    * Create a domain
+    * 
+    * @param domainName the domain name
+    * @param parentDomainName the parent domain name
+    * @param parentFirst whether to look in the parent first
+    * @return the domain
+    * @throws IllegalArgumentException for a null domain name
+    */
+   protected Domain createDomain(String domainName, String parentDomainName, boolean parentFirst)
+   {
+      if (domainName == null)
+         throw new IllegalArgumentException("Null domain name");
+      return new Domain(this, domainName, parentDomainName, parentFirst);
+   }
 }

Added: projects/jboss-cl/trunk/classloading/src/main/org/jboss/classloading/spi/dependency/ClassLoadingSpace.java
===================================================================
--- projects/jboss-cl/trunk/classloading/src/main/org/jboss/classloading/spi/dependency/ClassLoadingSpace.java	                        (rev 0)
+++ projects/jboss-cl/trunk/classloading/src/main/org/jboss/classloading/spi/dependency/ClassLoadingSpace.java	2008-07-10 09:55:12 UTC (rev 75592)
@@ -0,0 +1,345 @@
+/*
+* JBoss, Home of Professional Open Source
+* Copyright 2007, JBoss Inc., and individual contributors as indicated
+* by the @authors tag. See the copyright.txt in the distribution for a
+* full listing of individual contributors.
+*
+* This is free software; you can redistribute it and/or modify it
+* under the terms of the GNU Lesser General Public License as
+* published by the Free Software Foundation; either version 2.1 of
+* the License, or (at your option) any later version.
+*
+* This software is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+* Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public
+* License along with this software; if not, write to the Free
+* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+*/
+package org.jboss.classloading.spi.dependency;
+
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.Map.Entry;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.CopyOnWriteArraySet;
+
+import org.jboss.classloading.spi.metadata.Requirement;
+import org.jboss.logging.Logger;
+
+/**
+ * ClassLoadingSpace. This class does two stage join/resolve<p>
+ * 
+ * join - work out a module's capabilities/requirements and validate they are not inconsistent with what is already there
+ * resolve - resolve new requirements and potentially join with other spaces
+ * unjoin - remove a module from the space
+ * unresolve - work out the new state after a module splits
+ * 
+ * TODO JBCL-7 handle split packages
+ * @author <a href="adrian at jboss.com">Adrian Brock</a>
+ * @version $Revision: 1.1 $
+ */
+public class ClassLoadingSpace
+{
+   /** The log */
+   private static final Logger log = Logger.getLogger(ClassLoadingSpace.class);
+
+   /** Whether trace is enabled */
+   private static boolean trace = log.isTraceEnabled();
+   
+   /** The modules */
+   private Set<Module> modules = new CopyOnWriteArraySet<Module>();
+
+   /** The modules by package */
+   private Map<String, Module> modulesByPackage = new ConcurrentHashMap<String, Module>();
+   
+   /** The requirements for all modules */
+   private Map<Module, List<RequirementDependencyItem>> requirements = new ConcurrentHashMap<Module, List<RequirementDependencyItem>>();
+   
+   /**
+    * Get an unmodifiable set of the collections
+    * 
+    * @return the modules
+    */
+   public Set<Module> getModules()
+   {
+      return Collections.unmodifiableSet(modules);
+   }
+   
+   /**
+    * Join and resolve a module
+    * 
+    * @param module the module to add
+    * @throws IllegalArgumentException for a null module
+    */
+   synchronized void joinAndResolve(Module module)
+   {
+      if (module == null)
+         throw new IllegalArgumentException("Null module");
+
+      trace = log.isTraceEnabled();
+   
+      join(module);
+      try
+      {
+         resolve(module);
+      }
+      catch (Throwable t)
+      {
+         split(module);
+         if (t instanceof RuntimeException)
+            throw (RuntimeException) t;
+         if (t instanceof Error)
+            throw (Error) t;
+         throw new RuntimeException(modules + " could not join " + this, t);
+      }
+   }
+   
+   /**
+    * Join with a set of modules
+    * 
+    * @param modules the modules
+    * @throws IllegalArgumentException for null modules
+    */
+   synchronized void joinAndResolve(Set<Module> modules)
+   {
+      if (modules == null)
+         throw new IllegalArgumentException("Null modules");
+
+      Map<Module, ClassLoadingSpace> previous = new HashMap<Module, ClassLoadingSpace>();
+      try
+      {
+         for (Module module : modules)
+         {
+            ClassLoadingSpace space = module.getClassLoadingSpace();
+            join(module);
+            previous.put(module, space);
+            resolve(module);
+         }
+      }
+      catch (Throwable t)
+      {
+         // Revert the previous joins
+         for (Entry<Module, ClassLoadingSpace> entry : previous.entrySet())
+         {
+            Module module = entry.getKey();
+            ClassLoadingSpace space = entry.getValue();
+            
+            split(module);
+            try
+            {
+               space.join(module);
+            }
+            catch (Throwable t2)
+            {
+               log.error(module + " could not join " + space, t);
+               throw new RuntimeException("BUG: " + module + " could not rejoin " + space + " after failing to join " + this, t2);
+            }
+         }
+         if (t instanceof RuntimeException)
+            throw (RuntimeException) t;
+         if (t instanceof Error)
+            throw (Error) t;
+         throw new RuntimeException(modules + " could not join " + this, t);
+      }
+   }
+
+   /**
+    * Join with a classloading space
+    * 
+    * @param space the classloading space
+    * @throws IllegalArgumentException for null space
+    */
+   void joinAndResolve(ClassLoadingSpace space)
+   {
+      if (space == null)
+         throw new IllegalArgumentException("Null space");
+      if (space == this)
+         return;
+      
+      int ourSize = getModules().size();
+      int otherSize = space.getModules().size();
+      
+      if (ourSize >= otherSize)
+         joinAndResolve(space.getModules());
+      else
+         space.joinAndResolve(getModules());
+   }
+   
+   /**
+    * Split with a module
+    * 
+    * @param module the module to remove
+    * @throws IllegalArgumentException for a null module
+    * @throws IllegalStateException if the module is not associated with this classloading space
+    */
+   synchronized void split(Module module)
+   {
+      if (module == null)
+         throw new IllegalArgumentException("Null module");
+
+      ClassLoadingSpace other = module.getClassLoadingSpace();
+      if (other != this)
+         throw new IllegalStateException(module + " has the wrong classloading space: expected=" + this + " was " + other);
+
+      unjoin(module);
+      unresolve(module);
+   }
+   
+   /**
+    * Join with a module
+    * 
+    * @param module the module to add
+    * @throws IllegalArgumentException for a null module
+    */
+   private void join(Module module)
+   {
+      if (module == null)
+         throw new IllegalArgumentException("Null module");
+      // Nothing to do
+      ClassLoadingSpace other = module.getClassLoadingSpace();
+      if (other == this)
+         return;
+      
+      if (trace)
+         log.trace(module + " joining " + this);
+
+      // The packages exported by this module (excluding optional packages)
+      List<String> exportedPackages = module.determinePackageNames(false);
+
+      // Check there are no conflicting packages
+      if (exportedPackages != null && exportedPackages.isEmpty() == false)
+      {
+         for (String exportedPackage : exportedPackages)
+         {
+            Module otherModule = modulesByPackage.get(exportedPackage);
+            // TODO JBCL-7 ERRORS
+            if (otherModule != null)
+               throw new IllegalStateException(module + " cannot be added because it is exports package " + exportedPackage + " which conflicts with " + otherModule);
+         }
+      }
+
+      // Check our requirements are consistent with the other requirements
+      List<RequirementDependencyItem> moduleDependencies = module.getDependencies();
+      if (requirements.isEmpty() == false)
+      {
+         if (moduleDependencies != null && moduleDependencies.isEmpty() == false)
+         {
+            for (RequirementDependencyItem dependency : moduleDependencies)
+            {
+               Requirement requirement = dependency.getRequirement();
+               for (Entry<Module, List<RequirementDependencyItem>> entry : requirements.entrySet())
+               {
+                  Module otherModule = entry.getKey();
+                  List<RequirementDependencyItem> dependencies = entry.getValue();
+                  for (RequirementDependencyItem otherDependency : dependencies)
+                  {
+                     Requirement otherRequirement = otherDependency.getRequirement();
+                     // TODO JBCL-7 ERRORS
+                     if (requirement.isConsistent(otherRequirement) == false)
+                        throw new IllegalStateException(module + " has a requirement " + requirement + " which is inconsistent with " + otherRequirement + " from " + otherModule);
+                  }
+               }
+            }
+         }
+      }
+      
+      // Update the exported packages
+      if (exportedPackages != null && exportedPackages.isEmpty() == false)
+      {
+         for (String exportedPackage : exportedPackages)
+            modulesByPackage.put(exportedPackage, module);
+      }
+      
+      // Remember the module requirements
+      if (moduleDependencies != null && moduleDependencies.isEmpty() == false)
+         requirements.put(module, moduleDependencies);
+      
+      // Remove from any previous space
+      if (other != null)
+         other.split(module);
+      
+      // This module is now part of our space
+      modules.add(module);
+      module.setClassLoadingSpace(this);
+   }
+   
+   /**
+    * Unjoin a module
+    * 
+    * @param module the module to remove
+    */
+   private void unjoin(Module module)
+   {
+      if (trace)
+         log.trace(module + " unjoining " + this);
+      
+      // Remove the exported packages for this module
+      List<String> packageNames = module.determinePackageNames(false);
+      if (packageNames != null)
+      {
+         for (String packageName : packageNames)
+         {
+            Module removed = modulesByPackage.remove(packageName);
+            if (removed != module)
+               throw new IllegalStateException("BUG: Removed module " + removed + " for package " + packageName + " is not the expected module: " + module);
+         }
+      }
+
+      // Remove the module requirements from the classloading space
+      requirements.remove(module);
+      
+      // No longer part of this classloading space
+      modules.remove(module);
+      module.setClassLoadingSpace(null);
+   }
+   
+   /**
+    * Resolve a module
+    * 
+    * @param module the module to resolve
+    */
+   synchronized void resolve(Module module)
+   {
+      if (trace)
+         log.trace(module + " resolving " + this);
+
+      List<RequirementDependencyItem> moduleDependencies = requirements.get(module);
+      if (moduleDependencies != null)
+      {
+         for (RequirementDependencyItem dependency : moduleDependencies)
+         {
+            if (dependency.isResolved() == false)
+            {
+               Module otherModule = module.resolveModule(dependency, false);
+               if (otherModule != null)
+               {
+                  // Do we need to join with another classloading space?
+                  ClassLoadingSpace space = otherModule.getClassLoadingSpace();
+                  if (this != space)
+                     space.joinAndResolve(this);
+               }
+            }
+         }
+      }
+   }
+   
+   /**
+    * Unresolve a module
+    * 
+    * @param module the module to resolve
+    */
+   private void unresolve(Module module)
+   {
+      if (trace)
+         log.trace(module + " unresolving " + this);
+      
+      // Nothing yet. Could try to split classloading spaces if they now have disjoint subsets?
+   }
+}

Modified: projects/jboss-cl/trunk/classloading/src/main/org/jboss/classloading/spi/dependency/Domain.java
===================================================================
--- projects/jboss-cl/trunk/classloading/src/main/org/jboss/classloading/spi/dependency/Domain.java	2008-07-10 09:41:53 UTC (rev 75591)
+++ projects/jboss-cl/trunk/classloading/src/main/org/jboss/classloading/spi/dependency/Domain.java	2008-07-10 09:55:12 UTC (rev 75592)
@@ -28,7 +28,7 @@
 
 import org.jboss.classloading.spi.metadata.Capability;
 import org.jboss.classloading.spi.metadata.Requirement;
-import org.jboss.dependency.spi.Controller;
+import org.jboss.logging.Logger;
 
 /**
  * Domain.
@@ -38,9 +38,21 @@
  */
 public class Domain
 {
+   /** The log */
+   private static final Logger log = Logger.getLogger(Domain.class);
+   
    /** The domain name */
    private String name;
+
+   /** The classloading */
+   private ClassLoading classLoading;
+
+   /** The parent domain name */
+   private String parentDomainName;
    
+   /** Whether we are parent first */
+   private boolean parentFirst;
+   
    /** The registered modules in registration order */
    private List<Module> modules = new CopyOnWriteArrayList<Module>();
    
@@ -50,14 +62,22 @@
    /**
     * Create a new Domain.
     * 
+    * @param classLoading the classloading 
     * @param name the name
-    * @throws IllegalArgumentException for a null domain
+    * @param parentDomainName  the parent domain name
+    * @param parentFirst whether to check the parent first
+    * @throws IllegalArgumentException for a null domain or classloading
     */
-   public Domain(String name)
+   public Domain(ClassLoading classLoading, String name, String parentDomainName, boolean parentFirst)
    {
       if (name == null)
          throw new IllegalArgumentException("Null name");
+      if (classLoading == null)
+         throw new IllegalArgumentException("Null classLoading");
+      this.classLoading = classLoading;
       this.name = name;
+      this.parentDomainName = parentDomainName;
+      this.parentFirst = parentFirst;
    }
 
    /**
@@ -71,6 +91,33 @@
    }
 
    /**
+    * Get the parentDomainName.
+    * 
+    * @return the parentDomainName.
+    */
+   public String getParentDomainName()
+   {
+      return parentDomainName;
+   }
+
+   public Domain getParentDomain()
+   {
+      if (parentDomainName != null)
+         return classLoading.getDomain(parentDomainName);
+      return null;
+   }
+   
+   /**
+    * Get the parentFirst.
+    * 
+    * @return the parentFirst.
+    */
+   public boolean isParentFirst()
+   {
+      return parentFirst;
+   }
+
+   /**
     * Add a module
     * 
     * @param module the module
@@ -87,12 +134,22 @@
       String contextName = module.getContextName();
       if (modulesByName.containsKey(contextName))
          throw new IllegalArgumentException("The context " + contextName + " is already registered in domain " + getName());
+
+      log.debug(this + " add module " + module);
+      
       module.setDomain(this);
       modulesByName.put(contextName, module);
       modules.add(module);
       try
       {
          module.createDependencies();
+
+         // Skip the classloader space checking when it is import all
+         if (module.isImportAll() == false)
+         {
+            ClassLoadingSpace space = new ClassLoadingSpace();
+            space.joinAndResolve(module);
+         }
       }
       catch (Throwable t)
       {
@@ -105,7 +162,30 @@
             throw new RuntimeException("Error adding module " + module, t);
       }
    }
+   
+   /**
+    * Remove a deployment
+    * 
+    * @param module the module
+    * @throws IllegalArgumentException for a null parameter
+    */
+   protected synchronized void removeModule(Module module)
+   {
+      if (module == null)
+         throw new IllegalArgumentException("Null module");
 
+      log.debug(this + " add module " + module);
+      
+      modulesByName.remove(module.getContextName());
+      modules.remove(module);
+      module.setDomain(null);
+      module.removeDependencies();
+      
+      ClassLoadingSpace space = module.getClassLoadingSpace();
+      if (space != null)
+         space.split(module);
+   }
+
    /**
     * Get a module for a context name
     * 
@@ -116,23 +196,43 @@
    {
       if (name == null)
          throw new IllegalArgumentException("Null module name");
-      return modulesByName.get(name);
+
+      Module module = modulesByName.get(name);
+      if (module != null)
+         return module;
+      Domain parent = getParentDomain();
+      if (parent != null)
+         return parent.getModule(name);
+      return null;
    }
    
    /**
-    * Resolve the requirement
+    * Resolve a requirement to a module
     * 
-    * @param controller the controller
     * @param module the module
     * @param requirement the requirement
     * @return the resolved name or null if not resolved
     */
-   protected Object resolve(Controller controller, Module module, Requirement requirement)
+   protected Module resolveModule(Module module, Requirement requirement)
    {
-      // TODO JBMICROCONT-182 include parent domains in requirements
-      // TODO JBMICROCONT-182 check consistency of re-exports
-      // TODO JBMICROCONT-182 check for self-dependency
-      // TODO JBMICROCONT-182 test circularity
+      // First check the parent domain has been setup
+      Domain parentDomain = null;
+      if (parentDomainName != null)
+      {
+         parentDomain = getParentDomain();
+         if (parentDomain == null)
+            return null;
+      }
+
+      // Check the parent first when required
+      if (parentDomain != null && parentFirst == true)
+      {
+         Module result = parentDomain.resolveModule(module, requirement);
+         if (result != null)
+            return result;
+      }
+      
+      // TODO JBCL-7 check for self-dependency/circularity
       for (Module other : modules)
       {
          List<Capability> capabilities = other.getCapabilities();
@@ -141,26 +241,24 @@
             for (Capability capability : capabilities)
             {
                if (capability.resolves(module, requirement))
-                  return other.getContextName();
+                  return other;
             }
          }
       }
+
+      // Check the parent afterwards when required
+      if (parentDomain != null && parentFirst == false)
+         return parentDomain.resolveModule(module, requirement);
+      
       return null;
    }
    
-   /**
-    * Remove a deployment
-    * 
-    * @param module the module
-    * @throws IllegalArgumentException for a null parameter
-    */
-   protected synchronized void removeModule(Module module)
+   @Override
+   public String toString()
    {
-      if (module == null)
-         throw new IllegalArgumentException("Null module");
-      modulesByName.remove(module.getContextName());
-      modules.remove(module);
-      module.setDomain(null);
-      module.removeDependencies();
+      StringBuilder builder = new StringBuilder();
+      builder.append(super.toString());
+      builder.append('{').append(getName()).append('}');
+      return builder.toString();
    }
 }

Modified: projects/jboss-cl/trunk/classloading/src/main/org/jboss/classloading/spi/dependency/Module.java
===================================================================
--- projects/jboss-cl/trunk/classloading/src/main/org/jboss/classloading/spi/dependency/Module.java	2008-07-10 09:41:53 UTC (rev 75591)
+++ projects/jboss-cl/trunk/classloading/src/main/org/jboss/classloading/spi/dependency/Module.java	2008-07-10 09:55:12 UTC (rev 75592)
@@ -38,10 +38,10 @@
 import org.jboss.classloading.spi.metadata.ClassLoadingMetaDataFactory;
 import org.jboss.classloading.spi.metadata.ExportAll;
 import org.jboss.classloading.spi.metadata.ExportPackages;
+import org.jboss.classloading.spi.metadata.OptionalPackages;
 import org.jboss.classloading.spi.metadata.Requirement;
 import org.jboss.classloading.spi.visitor.ResourceFilter;
 import org.jboss.classloading.spi.visitor.ResourceVisitor;
-import org.jboss.dependency.spi.Controller;
 import org.jboss.dependency.spi.ControllerContext;
 import org.jboss.dependency.spi.ControllerState;
 
@@ -58,6 +58,9 @@
    
    /** Our cached capabilities */
    private List<Capability> capabilities;
+   
+   /** Our cached requirements */
+   private List<Requirement> requirements;
 
    /** The controller context */
    private ControllerContext context;
@@ -65,6 +68,9 @@
    /** The domain */
    private Domain domain;
 
+   /** The classloading space */
+   private ClassLoadingSpace space;
+   
    /** The requirements */
    private List<RequirementDependencyItem> requirementDependencies;
    
@@ -141,6 +147,16 @@
    }
    
    /**
+    * Whether this is a valid  module
+    * 
+    * @return true when valid
+    */
+   public boolean isValid()
+   {
+      return domain != null;
+   }
+   
+   /**
     * Get the domain name.
     * 
     * @return the domain name.
@@ -190,6 +206,26 @@
    }
 
    /**
+    * Get the classloading space.
+    * 
+    * @return the space.
+    */
+   ClassLoadingSpace getClassLoadingSpace()
+   {
+      return space;
+   }
+
+   /**
+    * Set the classloading space.
+    * 
+    * @param space the space.
+    */
+   void setClassLoadingSpace(ClassLoadingSpace space)
+   {
+      this.space = space;
+   }
+
+   /**
     * Get the export all for the module
     * 
     * @return the export all
@@ -474,8 +510,21 @@
     */
    public String[] getPackageNames()
    {
-      List<String> packageNames = new ArrayList<String>();
+      List<String> packageNames = determinePackageNames(true);
+      return packageNames.toArray(new String[packageNames.size()]);
+   }
 
+   /**
+    * Determine the package names
+    * 
+    * TODO JBCL-7 Better handling of conflicts for optional packages
+    * @param optional whether to include optional packages
+    * @return the package names
+    */
+   public List<String> determinePackageNames(boolean optional)
+   {
+      List<String> packageNames = Collections.emptyList();
+
       List<Capability> capabilities = getCapabilities();
       if (capabilities != null && capabilities.isEmpty() == false)
       {
@@ -486,7 +535,11 @@
                ExportPackages exported = (ExportPackages) capability;
                Set<String> exportPackages = exported.getPackageNames(this);
                if (exportPackages != null)
+               {
+                  if (packageNames.isEmpty())
+                     packageNames = new ArrayList<String>();
                   packageNames.addAll(exportPackages);
+               }
             }
          }
       }
@@ -500,13 +553,27 @@
             {
                ExportPackages exported = (ExportPackages) requirement;
                Set<String> exportPackages = exported.getPackageNames(this);
-               if (exportPackages != null)
-                  packageNames.addAll(exportPackages);
+               if (optional || requirement.isOptional() == false)
+               {
+                  if (exportPackages != null && exportPackages.isEmpty() == false)
+                  {
+                     if (packageNames.isEmpty())
+                        packageNames = new ArrayList<String>();
+                     packageNames.addAll(exportPackages);
+                  }
+               }
             }
+            else if (optional == false && requirement instanceof OptionalPackages)
+            {
+               OptionalPackages exported = (OptionalPackages) requirement;
+               Set<String> optionalPackages = exported.getOptionalPackageNames(this);
+               if (optionalPackages != null && packageNames.isEmpty() == false)
+                  packageNames.removeAll(optionalPackages);
+            }
          }
       }
 
-      return packageNames.toArray(new String[packageNames.size()]);
+      return packageNames;
    }
    
    /**
@@ -526,6 +593,25 @@
     */
    public List<Requirement> getRequirements()
    {
+      // Have we already worked this out?
+      if (requirements != null)
+         return requirements;
+      
+      // Are there any configured ones?
+      List<Requirement> requirements = determineRequirements();
+      
+      // Cache it
+      this.requirements = requirements;
+      return requirements;
+   }
+
+   /**
+    * Determine the requirements.
+    * 
+    * @return the requirements.
+    */
+   public List<Requirement> determineRequirements()
+   {
       return Collections.emptyList();
    }
 
@@ -539,6 +625,11 @@
       return null;
    }
    
+   List<RequirementDependencyItem> getDependencies()
+   {
+      return requirementDependencies;
+   }
+   
    /**
     * Create the dependencies for the module
     */
@@ -617,15 +708,20 @@
    }
    
    /**
-    * Resolve the requirement
+    * Resolve a requirement
     * 
-    * @param controller the controller
-    * @param requirement the requirement
+    * @param dependency the dependency the dependency
+    * @param resolveSpace whether to resolve the module in the classloading space
     * @return the resolved name or null if not resolved
     */
-   protected Object resolve(Controller controller, Requirement requirement)
+   protected Module resolveModule(RequirementDependencyItem dependency, boolean resolveSpace)
    {
-      return checkDomain().resolve(controller, this, requirement);
+      ClassLoadingSpace space = getClassLoadingSpace();
+      if (resolveSpace && space != null)
+         space.resolve(this);
+
+      Requirement requirement = dependency.getRequirement();
+      return checkDomain().resolveModule(this, requirement);
    }
    
    /**
@@ -633,7 +729,9 @@
     */
    public void release()
    {
-      checkDomain().removeModule(this);
+      Domain domain = this.domain;
+      if (domain != null)
+         domain.removeModule(this);
       reset();
    }
    
@@ -643,6 +741,7 @@
    public void reset()
    {
       this.capabilities = null;
+      this.requirements = null;
    }
 
    @Override

Modified: projects/jboss-cl/trunk/classloading/src/main/org/jboss/classloading/spi/dependency/RequirementDependencyItem.java
===================================================================
--- projects/jboss-cl/trunk/classloading/src/main/org/jboss/classloading/spi/dependency/RequirementDependencyItem.java	2008-07-10 09:41:53 UTC (rev 75591)
+++ projects/jboss-cl/trunk/classloading/src/main/org/jboss/classloading/spi/dependency/RequirementDependencyItem.java	2008-07-10 09:55:12 UTC (rev 75592)
@@ -84,9 +84,10 @@
    public boolean resolve(Controller controller)
    {
       Requirement requirement = getRequirement();
-      Object iDependOn = getModule().resolve(controller, requirement);
-      if (iDependOn != null)
+      Module module = getModule().resolveModule(this, true);
+      if (module != null)
       {
+         Object iDependOn = module.getContextName();
          ControllerContext context = controller.getContext(iDependOn, getDependentState());
          if (context != null)
          {

Modified: projects/jboss-cl/trunk/classloading/src/main/org/jboss/classloading/spi/dependency/helpers/ClassLoadingMetaDataModule.java
===================================================================
--- projects/jboss-cl/trunk/classloading/src/main/org/jboss/classloading/spi/dependency/helpers/ClassLoadingMetaDataModule.java	2008-07-10 09:41:53 UTC (rev 75591)
+++ projects/jboss-cl/trunk/classloading/src/main/org/jboss/classloading/spi/dependency/helpers/ClassLoadingMetaDataModule.java	2008-07-10 09:55:12 UTC (rev 75592)
@@ -160,7 +160,7 @@
    }
 
    @Override
-   public List<Requirement> getRequirements()
+   public List<Requirement> determineRequirements()
    {
       return classLoadingMetaData.getRequirements().getRequirements();
    }

Modified: projects/jboss-cl/trunk/classloading/src/main/org/jboss/classloading/spi/dependency/policy/ClassLoaderPolicyModule.java
===================================================================
--- projects/jboss-cl/trunk/classloading/src/main/org/jboss/classloading/spi/dependency/policy/ClassLoaderPolicyModule.java	2008-07-10 09:41:53 UTC (rev 75591)
+++ projects/jboss-cl/trunk/classloading/src/main/org/jboss/classloading/spi/dependency/policy/ClassLoaderPolicyModule.java	2008-07-10 09:55:12 UTC (rev 75592)
@@ -78,6 +78,9 @@
    {
       if (system == null)
          throw new IllegalArgumentException("Null classloader system");
+
+      if (isValid() == false)
+         throw new IllegalStateException("Module " + this + " is not registered, see previous error messages");
       
       String domainName = getDeterminedDomainName();
       ParentPolicy parentPolicy = getDeterminedParentPolicy();
@@ -102,6 +105,9 @@
       if (parent == null)
          throw new IllegalArgumentException("Null parent");
 
+      if (isValid() == false)
+         throw new IllegalStateException("Module " + this + " is not registered, see previous error messages");
+
       Loader loader = new ClassLoaderToLoaderAdapter(parent);
       ClassLoader result = registerClassLoaderPolicy(system, loader); 
       this.classLoader = result;
@@ -119,6 +125,9 @@
    {
       if (system == null)
          throw new IllegalArgumentException("Null classloader system");
+
+      if (isValid() == false)
+         throw new IllegalStateException("Module " + this + " is not registered, see previous error messages");
       
       String domainName = getDeterminedDomainName();
       ParentPolicy parentPolicy = getDeterminedParentPolicy();

Added: projects/jboss-cl/trunk/classloading/src/main/org/jboss/classloading/spi/metadata/OptionalPackages.java
===================================================================
--- projects/jboss-cl/trunk/classloading/src/main/org/jboss/classloading/spi/metadata/OptionalPackages.java	                        (rev 0)
+++ projects/jboss-cl/trunk/classloading/src/main/org/jboss/classloading/spi/metadata/OptionalPackages.java	2008-07-10 09:55:12 UTC (rev 75592)
@@ -0,0 +1,43 @@
+/*
+* JBoss, Home of Professional Open Source
+* Copyright 2007, JBoss Inc., and individual contributors as indicated
+* by the @authors tag. See the copyright.txt in the distribution for a
+* full listing of individual contributors.
+*
+* This is free software; you can redistribute it and/or modify it
+* under the terms of the GNU Lesser General Public License as
+* published by the Free Software Foundation; either version 2.1 of
+* the License, or (at your option) any later version.
+*
+* This software is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+* Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public
+* License along with this software; if not, write to the Free
+* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+*/
+package org.jboss.classloading.spi.metadata;
+
+import java.util.Set;
+
+import org.jboss.classloading.spi.dependency.Module;
+
+/**
+ * OptionalPackage.
+ * 
+ * @author <a href="adrian at jboss.com">Adrian Brock</a>
+ * @version $Revision: 1.1 $
+ */
+public interface OptionalPackages
+{
+   /**
+    * Get the package names
+    *
+    * @param module the module
+    * @return the package names
+    */
+   Set<String> getOptionalPackageNames(Module module);
+}

Modified: projects/jboss-cl/trunk/classloading/src/main/org/jboss/classloading/spi/metadata/Requirement.java
===================================================================
--- projects/jboss-cl/trunk/classloading/src/main/org/jboss/classloading/spi/metadata/Requirement.java	2008-07-10 09:41:53 UTC (rev 75591)
+++ projects/jboss-cl/trunk/classloading/src/main/org/jboss/classloading/spi/metadata/Requirement.java	2008-07-10 09:55:12 UTC (rev 75592)
@@ -58,4 +58,15 @@
     * @return true if the requirement is dynamic
     */
    boolean isDynamic();
+   
+   /**
+    * Check whether this requirement is consistent with another requirement.<p>
+    * 
+    * Typically they will be inconsistent if they are the same type,
+    * have the same name but a different version
+    * 
+    * @param other the other requirement
+    * @return true when consistent, false when inconsistent
+    */
+   boolean isConsistent(Requirement other);
 }

Modified: projects/jboss-cl/trunk/classloading/src/main/org/jboss/classloading/spi/metadata/helpers/AbstractRequirement.java
===================================================================
--- projects/jboss-cl/trunk/classloading/src/main/org/jboss/classloading/spi/metadata/helpers/AbstractRequirement.java	2008-07-10 09:41:53 UTC (rev 75591)
+++ projects/jboss-cl/trunk/classloading/src/main/org/jboss/classloading/spi/metadata/helpers/AbstractRequirement.java	2008-07-10 09:55:12 UTC (rev 75592)
@@ -129,7 +129,43 @@
    {
       this.reExport = reExport;
    }
+   
+   public boolean isConsistent(Requirement other)
+   {
+      return isConsistent(other, null);
+   }
 
+   /**
+    * Check whether the requirements are consistent
+    * 
+    * @param other the other requirement
+    * @param requirementType the class to check when looking for inconsistencies (uses getClass() when null)
+    * @return true when consistent, false otherwise
+    */
+   protected boolean isConsistent(Requirement other, Class<? extends AbstractRequirement> requirementType)
+   {
+      if (other == null)
+         throw new IllegalArgumentException("Null requirement");
+      if (requirementType == null)
+         requirementType = getClass();
+      
+      // Not our type
+      if (requirementType.isInstance(other) == false)
+         return true;
+      
+      AbstractRequirement otherRequirement = (AbstractRequirement) other;
+      // Not the same name
+      String name = getName();
+      String otherName = otherRequirement.getName();
+      if (name.equals(otherName) == false)
+         return true;
+
+      // Check the version ranges are consistent
+      VersionRange range = getVersionRange();
+      VersionRange otherRange = otherRequirement.getVersionRange();
+      return range.isConsistent(otherRange);
+   }
+
    @Override
    public boolean equals(Object obj)
    {

Modified: projects/jboss-cl/trunk/classloading/src/main/org/jboss/classloading/spi/version/VersionRange.java
===================================================================
--- projects/jboss-cl/trunk/classloading/src/main/org/jboss/classloading/spi/version/VersionRange.java	2008-07-10 09:41:53 UTC (rev 75591)
+++ projects/jboss-cl/trunk/classloading/src/main/org/jboss/classloading/spi/version/VersionRange.java	2008-07-10 09:55:12 UTC (rev 75592)
@@ -186,6 +186,49 @@
       return true;
    }
 
+   /**
+    * Check whether two version ranges are consistent
+    * 
+    * @param other the other version
+    * @return true when the version ranges "overlap"
+    */
+   public boolean isConsistent(VersionRange other)
+   {
+      // No version range is consistent with ours
+      if (other == null)
+         return true;
+      
+      Object otherLow = other.getLow();
+      Object otherHigh = other.getHigh();
+      
+      VersionComparatorRegistry comparator = VersionComparatorRegistry.getInstance();
+      
+      // Other low is "lower"
+      int comparison = comparator.compare(low, otherLow);
+      if (comparison > 0 || (lowInclusive == false && comparison == 0))
+      {
+         // Just need to check that the other high is not lower
+         if (otherHigh == null)
+            return true;
+         comparison = comparator.compare(low, otherHigh);
+         return (comparison > 0 || (lowInclusive == false && comparison == 0)) == false;
+      }
+
+      // So the other low is "bigger" than our low
+      
+      // We have no high so we are done
+      if (high == null)
+         return true;
+      
+      // Check the other low is not "bigger" than our higher
+      comparison = comparator.compare(high, otherLow);
+      if (comparison < 0 || (highInclusive == false && comparison == 0))
+         return false;
+      
+      // The low is in our range so we are done
+      return true;
+   }
+   
    @Override
    public boolean equals(Object obj)
    {

Modified: projects/jboss-cl/trunk/classloading/src/tests/org/jboss/test/classloading/dependency/DependencyTestSuite.java
===================================================================
--- projects/jboss-cl/trunk/classloading/src/tests/org/jboss/test/classloading/dependency/DependencyTestSuite.java	2008-07-10 09:41:53 UTC (rev 75591)
+++ projects/jboss-cl/trunk/classloading/src/tests/org/jboss/test/classloading/dependency/DependencyTestSuite.java	2008-07-10 09:55:12 UTC (rev 75592)
@@ -25,8 +25,11 @@
 import junit.framework.TestSuite;
 import junit.textui.TestRunner;
 
+import org.jboss.test.classloading.dependency.test.ConflictingPackageUnitTestCase;
+import org.jboss.test.classloading.dependency.test.ConflictingRequirementUnitTestCase;
 import org.jboss.test.classloading.dependency.test.DependencyUnitTestCase;
 import org.jboss.test.classloading.dependency.test.DomainUnitTestCase;
+import org.jboss.test.classloading.dependency.test.HierarchicalDomainUnitTestCase;
 import org.jboss.test.classloading.dependency.test.ImportAllUnitTestCase;
 import org.jboss.test.classloading.dependency.test.MockClassLoadingMetaDataUnitTestCase;
 import org.jboss.test.classloading.dependency.test.ModuleDependencyUnitTestCase;
@@ -73,6 +76,9 @@
       suite.addTest(ReExportPackageUnitTestCase.suite());
       suite.addTest(UsesPackageUnitTestCase.suite());
       suite.addTest(MockResourceVisitorUnitTestCase.suite());
+      suite.addTest(HierarchicalDomainUnitTestCase.suite());
+      suite.addTest(ConflictingPackageUnitTestCase.suite());
+      suite.addTest(ConflictingRequirementUnitTestCase.suite());
 
       return suite;
    }

Modified: projects/jboss-cl/trunk/classloading/src/tests/org/jboss/test/classloading/dependency/test/AbstractMockClassLoaderUnitTest.java
===================================================================
--- projects/jboss-cl/trunk/classloading/src/tests/org/jboss/test/classloading/dependency/test/AbstractMockClassLoaderUnitTest.java	2008-07-10 09:41:53 UTC (rev 75591)
+++ projects/jboss-cl/trunk/classloading/src/tests/org/jboss/test/classloading/dependency/test/AbstractMockClassLoaderUnitTest.java	2008-07-10 09:55:12 UTC (rev 75592)
@@ -92,7 +92,13 @@
          MockClassLoaderPolicyModule module = assertModule(context);
          Object target = context.getTarget();
          assertNotNull(target);
-         fail("Should not be able to create classloader: " + module.registerClassLoaderPolicy(system));
+         try
+         {
+            fail("Should not be able to create classloader: " + module.registerClassLoaderPolicy(system));
+         }
+         catch (IllegalStateException expected)
+         {
+         }
       }
    }
    

Added: projects/jboss-cl/trunk/classloading/src/tests/org/jboss/test/classloading/dependency/test/ConflictingPackageUnitTestCase.java
===================================================================
--- projects/jboss-cl/trunk/classloading/src/tests/org/jboss/test/classloading/dependency/test/ConflictingPackageUnitTestCase.java	                        (rev 0)
+++ projects/jboss-cl/trunk/classloading/src/tests/org/jboss/test/classloading/dependency/test/ConflictingPackageUnitTestCase.java	2008-07-10 09:55:12 UTC (rev 75592)
@@ -0,0 +1,229 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2008, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.test.classloading.dependency.test;
+
+import junit.framework.Test;
+
+import org.jboss.classloading.spi.dependency.policy.mock.MockClassLoadingMetaData;
+import org.jboss.classloading.spi.metadata.ClassLoadingMetaDataFactory;
+import org.jboss.kernel.spi.dependency.KernelControllerContext;
+import org.jboss.test.classloading.dependency.support.a.A;
+import org.jboss.test.classloading.dependency.support.b.B;
+
+/**
+ * ConflictingPackageUnitTestCase.
+ * 
+ * @author <a href="adrian at jboss.com">Adrian Brock</a>
+ * @version $Revision: 1.1 $
+ */
+public class ConflictingPackageUnitTestCase extends AbstractMockClassLoaderUnitTest
+{
+   public static Test suite()
+   {
+      return suite(ConflictingPackageUnitTestCase.class);
+   }
+
+   public ConflictingPackageUnitTestCase(String name)
+   {
+      super(name);
+   }
+   
+   public void testConflictingPackage() throws Exception
+   {
+      ClassLoadingMetaDataFactory factory = ClassLoadingMetaDataFactory.getInstance();
+      MockClassLoadingMetaData a1 = new MockClassLoadingMetaData("a1", "1.0.0");
+      a1.setPathsAndPackageNames(A.class);
+      KernelControllerContext contextA1 = install(a1);
+      try
+      {
+         ClassLoader clA1 = assertClassLoader(contextA1);
+         assertLoadClass(A.class, clA1);
+         assertLoadClassFail(B.class, clA1);
+
+         MockClassLoadingMetaData a2 = new MockClassLoadingMetaData("a2", "2.0.0");
+         a2.getRequirements().addRequirement(factory.createRequireModule("a1"));
+         a2.setPathsAndPackageNames(A.class);
+         KernelControllerContext contextA2 = install(a2);
+         try
+         {
+            assertNoClassLoader(contextA2);
+         }
+         finally
+         {
+            uninstall(contextA2);
+         }
+         assertNoClassLoader(contextA2);
+      }
+      finally
+      {
+         uninstall(contextA1);
+      }
+      assertNoClassLoader(contextA1);
+   }
+   
+   public void testConflictingPackageNoImport() throws Exception
+   {
+      MockClassLoadingMetaData a1 = new MockClassLoadingMetaData("a1", "1.0.0");
+      a1.setPathsAndPackageNames(A.class);
+      KernelControllerContext contextA1 = install(a1);
+      try
+      {
+         ClassLoader clA1 = assertClassLoader(contextA1);
+         assertLoadClass(A.class, clA1);
+         assertLoadClassFail(B.class, clA1);
+
+         MockClassLoadingMetaData a2 = new MockClassLoadingMetaData("a2", "2.0.0");
+         a2.setPathsAndPackageNames(A.class);
+         KernelControllerContext contextA2 = install(a2);
+         try
+         {
+            ClassLoader clA2 = assertClassLoader(contextA2);
+            assertLoadClass(A.class, clA2);
+            assertLoadClassFail(B.class, clA2);
+         }
+         finally
+         {
+            uninstall(contextA2);
+         }
+         assertNoClassLoader(contextA2);
+      }
+      finally
+      {
+         uninstall(contextA1);
+      }
+      assertNoClassLoader(contextA1);
+   }
+   
+   public void testConflictingPackageNoExport() throws Exception
+   {
+      ClassLoadingMetaDataFactory factory = ClassLoadingMetaDataFactory.getInstance();
+      MockClassLoadingMetaData a1 = new MockClassLoadingMetaData("a1", "1.0.0");
+      a1.setPaths(A.class);
+      KernelControllerContext contextA1 = install(a1);
+      try
+      {
+         ClassLoader clA1 = assertClassLoader(contextA1);
+         assertLoadClass(A.class, clA1);
+         assertLoadClassFail(B.class, clA1);
+
+         MockClassLoadingMetaData a2 = new MockClassLoadingMetaData("a2", "2.0.0");
+         a2.getRequirements().addRequirement(factory.createRequireModule("a1"));
+         a2.setPathsAndPackageNames(A.class);
+         KernelControllerContext contextA2 = install(a2);
+         try
+         {
+            ClassLoader clA2 = assertClassLoader(contextA2);
+            assertLoadClass(A.class, clA2);
+            assertLoadClassFail(B.class, clA2);
+         }
+         finally
+         {
+            uninstall(contextA2);
+         }
+         assertNoClassLoader(contextA2);
+      }
+      finally
+      {
+         uninstall(contextA1);
+      }
+      assertNoClassLoader(contextA1);
+   }
+   
+   public void testConflictingPackageUses() throws Exception
+   {
+      ClassLoadingMetaDataFactory factory = ClassLoadingMetaDataFactory.getInstance();
+      MockClassLoadingMetaData a1 = new MockClassLoadingMetaData("a1", "1.0.0");
+      a1.setPathsAndPackageNames(A.class);
+      KernelControllerContext contextA1 = install(a1);
+      try
+      {
+         ClassLoader clA1 = assertClassLoader(contextA1);
+         assertLoadClass(A.class, clA1);
+         assertLoadClassFail(B.class, clA1);
+
+         MockClassLoadingMetaData a2 = new MockClassLoadingMetaData("a2", "2.0.0");
+         a2.getRequirements().addRequirement(factory.createUsesPackage(A.class.getPackage().getName()));
+         a2.setPathsAndPackageNames(A.class);
+         KernelControllerContext contextA2 = install(a2);
+         try
+         {
+            ClassLoader clA2 = assertClassLoader(contextA2);
+            assertLoadClass(A.class, clA2, clA1);
+            assertLoadClassFail(B.class, clA2);
+         }
+         finally
+         {
+            uninstall(contextA2);
+         }
+         assertNoClassLoader(contextA2);
+      }
+      finally
+      {
+         uninstall(contextA1);
+      }
+      assertNoClassLoader(contextA1);
+   }
+   
+   public void testConflictingPackageRedeploy() throws Exception
+   {
+      ClassLoadingMetaDataFactory factory = ClassLoadingMetaDataFactory.getInstance();
+      MockClassLoadingMetaData a1 = new MockClassLoadingMetaData("a1", "1.0.0");
+      a1.getRequirements().addRequirement(factory.createRequireModule("a2"));
+      a1.setPathsAndPackageNames(A.class);
+      KernelControllerContext contextA1 = install(a1);
+      try
+      {
+         assertNoClassLoader(contextA1);
+
+         MockClassLoadingMetaData a2 = new MockClassLoadingMetaData("a2", "2.0.0");
+         a2.setPathsAndPackageNames(A.class);
+         KernelControllerContext contextA2 = install(a2);
+         try
+         {
+            ClassLoader clA2 = assertClassLoader(contextA2);
+            assertLoadClass(A.class, clA2);
+            assertLoadClassFail(B.class, clA2);
+            
+            uninstall(contextA1);
+
+            a1 = new MockClassLoadingMetaData("a1", "1.0.0");
+            a1.getRequirements().addRequirement(factory.createRequireModule("a2"));
+            a1.setPathsAndPackageNames(B.class);
+            contextA1 = install(a1);
+
+            ClassLoader clA1 = assertClassLoader(contextA1);
+            assertLoadClass(A.class, clA2);
+            assertLoadClass(B.class, clA1);
+         }
+         finally
+         {
+            uninstall(contextA2);
+         }
+         assertNoClassLoader(contextA2);
+      }
+      finally
+      {
+         uninstall(contextA1);
+      }
+      assertNoClassLoader(contextA1);
+   }
+}

Added: projects/jboss-cl/trunk/classloading/src/tests/org/jboss/test/classloading/dependency/test/ConflictingRequirementUnitTestCase.java
===================================================================
--- projects/jboss-cl/trunk/classloading/src/tests/org/jboss/test/classloading/dependency/test/ConflictingRequirementUnitTestCase.java	                        (rev 0)
+++ projects/jboss-cl/trunk/classloading/src/tests/org/jboss/test/classloading/dependency/test/ConflictingRequirementUnitTestCase.java	2008-07-10 09:55:12 UTC (rev 75592)
@@ -0,0 +1,346 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2008, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.test.classloading.dependency.test;
+
+import junit.framework.Test;
+
+import org.jboss.classloading.spi.dependency.policy.mock.MockClassLoadingMetaData;
+import org.jboss.classloading.spi.metadata.ClassLoadingMetaDataFactory;
+import org.jboss.classloading.spi.version.VersionRange;
+import org.jboss.kernel.spi.dependency.KernelControllerContext;
+import org.jboss.test.classloading.dependency.support.a.A;
+import org.jboss.test.classloading.dependency.support.b.B;
+import org.jboss.test.classloading.dependency.support.c.C;
+
+/**
+ * ConflictingPackageUnitTestCase.
+ * 
+ * @author <a href="adrian at jboss.com">Adrian Brock</a>
+ * @version $Revision: 1.1 $
+ */
+public class ConflictingRequirementUnitTestCase extends AbstractMockClassLoaderUnitTest
+{
+   public static Test suite()
+   {
+      return suite(ConflictingRequirementUnitTestCase.class);
+   }
+
+   public ConflictingRequirementUnitTestCase(String name)
+   {
+      super(name);
+   }
+   
+   public void testConflictingRequirement() throws Exception
+   {
+      ClassLoadingMetaDataFactory factory = ClassLoadingMetaDataFactory.getInstance();
+      MockClassLoadingMetaData a1 = new MockClassLoadingMetaData("a", "1.0.0");
+      a1.setPathsAndPackageNames(A.class);
+      KernelControllerContext contextA1 = install(a1);
+      try
+      {
+         ClassLoader clA1 = assertClassLoader(contextA1);
+         assertLoadClass(A.class, clA1);
+         assertLoadClassFail(B.class, clA1);
+         assertLoadClassFail(C.class, clA1);
+
+         MockClassLoadingMetaData a2 = new MockClassLoadingMetaData("a", "2.0.0");
+         a2.setPathsAndPackageNames(A.class);
+         KernelControllerContext contextA2 = install(a2);
+         try
+         {
+            ClassLoader clA2 = assertClassLoader(contextA2);
+            assertLoadClass(A.class, clA2);
+            assertLoadClassFail(B.class, clA2);
+            assertLoadClassFail(C.class, clA2);
+
+            MockClassLoadingMetaData b1 = new MockClassLoadingMetaData("b", "1.0.0");
+            b1.getRequirements().addRequirement(factory.createRequireModule("a", new VersionRange("2.0.0", "3.0.0")));
+            b1.setPathsAndPackageNames(B.class);
+            KernelControllerContext contextB1 = install(b1);
+            try
+            {
+               ClassLoader clB1 = assertClassLoader(contextB1);
+               assertLoadClass(B.class, clB1);
+               assertLoadClass(A.class, clB1, clA2);
+               assertLoadClassFail(C.class, clB1);
+
+               MockClassLoadingMetaData c1 = new MockClassLoadingMetaData("c", "1.0.0");
+               c1.getRequirements().addRequirement(factory.createRequireModule("b"));
+               c1.getRequirements().addRequirement(factory.createRequireModule("a", new VersionRange("1.0.0", "2.0.0")));
+               c1.setPathsAndPackageNames(C.class);
+               KernelControllerContext contextC1 = install(c1);
+               try
+               {
+                  assertNoClassLoader(contextC1);
+               }
+               finally
+               {
+                  uninstall(contextC1);
+               }
+               assertNoClassLoader(contextC1);
+            }
+            finally
+            {
+               uninstall(contextB1);
+            }
+            assertNoClassLoader(contextB1);
+         }
+         finally
+         {
+            uninstall(contextA2);
+         }
+         assertNoClassLoader(contextA2);
+      }
+      finally
+      {
+         uninstall(contextA1);
+      }
+      assertNoClassLoader(contextA1);
+   }
+   
+   public void testConflictingRequirementNoJoin() throws Exception
+   {
+      ClassLoadingMetaDataFactory factory = ClassLoadingMetaDataFactory.getInstance();
+      MockClassLoadingMetaData a1 = new MockClassLoadingMetaData("a", "1.0.0");
+      a1.setPathsAndPackageNames(A.class);
+      KernelControllerContext contextA1 = install(a1);
+      try
+      {
+         ClassLoader clA1 = assertClassLoader(contextA1);
+         assertLoadClass(A.class, clA1);
+         assertLoadClassFail(B.class, clA1);
+         assertLoadClassFail(C.class, clA1);
+
+         MockClassLoadingMetaData a2 = new MockClassLoadingMetaData("a", "2.0.0");
+         a2.setPathsAndPackageNames(A.class);
+         KernelControllerContext contextA2 = install(a2);
+         try
+         {
+            ClassLoader clA2 = assertClassLoader(contextA2);
+            assertLoadClass(A.class, clA2);
+            assertLoadClassFail(B.class, clA2);
+            assertLoadClassFail(C.class, clA2);
+
+            MockClassLoadingMetaData b1 = new MockClassLoadingMetaData("b", "1.0.0");
+            b1.getRequirements().addRequirement(factory.createRequireModule("a", new VersionRange("2.0.0", "3.0.0")));
+            b1.setPathsAndPackageNames(B.class);
+            KernelControllerContext contextB1 = install(b1);
+            try
+            {
+               ClassLoader clB1 = assertClassLoader(contextB1);
+               assertLoadClass(B.class, clB1);
+               assertLoadClass(A.class, clB1, clA2);
+               assertLoadClassFail(C.class, clB1);
+
+               MockClassLoadingMetaData c1 = new MockClassLoadingMetaData("c", "1.0.0");
+               c1.getRequirements().addRequirement(factory.createRequireModule("a", new VersionRange("1.0.0", "2.0.0")));
+               c1.setPathsAndPackageNames(C.class);
+               KernelControllerContext contextC1 = install(c1);
+               try
+               {
+                  ClassLoader clC1 = assertClassLoader(contextC1);
+                  assertLoadClass(C.class, clC1);
+                  assertLoadClass(A.class, clC1, clA1);
+                  assertLoadClassFail(B.class, clC1);
+               }
+               finally
+               {
+                  uninstall(contextC1);
+               }
+               assertNoClassLoader(contextC1);
+            }
+            finally
+            {
+               uninstall(contextB1);
+            }
+            assertNoClassLoader(contextB1);
+         }
+         finally
+         {
+            uninstall(contextA2);
+         }
+         assertNoClassLoader(contextA2);
+      }
+      finally
+      {
+         uninstall(contextA1);
+      }
+      assertNoClassLoader(contextA1);
+   }
+   
+   public void testRequirementIsConsistent() throws Exception
+   {
+      ClassLoadingMetaDataFactory factory = ClassLoadingMetaDataFactory.getInstance();
+      MockClassLoadingMetaData a1 = new MockClassLoadingMetaData("a", "1.0.0");
+      a1.setPathsAndPackageNames(A.class);
+      KernelControllerContext contextA1 = install(a1);
+      try
+      {
+         ClassLoader clA1 = assertClassLoader(contextA1);
+         assertLoadClass(A.class, clA1);
+         assertLoadClassFail(B.class, clA1);
+         assertLoadClassFail(C.class, clA1);
+
+         MockClassLoadingMetaData a2 = new MockClassLoadingMetaData("a", "2.0.0");
+         a2.setPathsAndPackageNames(A.class);
+         KernelControllerContext contextA2 = install(a2);
+         try
+         {
+            ClassLoader clA2 = assertClassLoader(contextA2);
+            assertLoadClass(A.class, clA2);
+            assertLoadClassFail(B.class, clA2);
+            assertLoadClassFail(C.class, clA2);
+
+            MockClassLoadingMetaData b1 = new MockClassLoadingMetaData("b", "1.0.0");
+            b1.getRequirements().addRequirement(factory.createRequireModule("a", new VersionRange("1.0.0", "2.0.0")));
+            b1.setPathsAndPackageNames(B.class);
+            KernelControllerContext contextB1 = install(b1);
+            try
+            {
+               ClassLoader clB1 = assertClassLoader(contextB1);
+               assertLoadClass(B.class, clB1);
+               assertLoadClass(A.class, clB1, clA1);
+               assertLoadClassFail(C.class, clB1);
+
+               MockClassLoadingMetaData c1 = new MockClassLoadingMetaData("c", "1.0.0");
+               c1.getRequirements().addRequirement(factory.createRequireModule("b"));
+               c1.getRequirements().addRequirement(factory.createRequireModule("a", new VersionRange("1.0.0", "2.0.0")));
+               c1.setPathsAndPackageNames(C.class);
+               KernelControllerContext contextC1 = install(c1);
+               try
+               {
+                  ClassLoader clC1 = assertClassLoader(contextC1);
+                  assertLoadClass(C.class, clC1);
+                  assertLoadClass(A.class, clC1, clA1);
+                  assertLoadClass(B.class, clC1, clB1);
+               }
+               finally
+               {
+                  uninstall(contextC1);
+               }
+               assertNoClassLoader(contextC1);
+            }
+            finally
+            {
+               uninstall(contextB1);
+            }
+            assertNoClassLoader(contextB1);
+         }
+         finally
+         {
+            uninstall(contextA2);
+         }
+         assertNoClassLoader(contextA2);
+      }
+      finally
+      {
+         uninstall(contextA1);
+      }
+      assertNoClassLoader(contextA1);
+   }
+   
+   public void testRequirementRedeploy() throws Exception
+   {
+      ClassLoadingMetaDataFactory factory = ClassLoadingMetaDataFactory.getInstance();
+      MockClassLoadingMetaData a1 = new MockClassLoadingMetaData("a", "1.0.0");
+      a1.setPathsAndPackageNames(A.class);
+      KernelControllerContext contextA1 = install(a1);
+      try
+      {
+         ClassLoader clA1 = assertClassLoader(contextA1);
+         assertLoadClass(A.class, clA1);
+         assertLoadClassFail(B.class, clA1);
+         assertLoadClassFail(C.class, clA1);
+
+         MockClassLoadingMetaData a2 = new MockClassLoadingMetaData("a", "2.0.0");
+         a2.setPathsAndPackageNames(A.class);
+         KernelControllerContext contextA2 = install(a2);
+         try
+         {
+            ClassLoader clA2 = assertClassLoader(contextA2);
+            assertLoadClass(A.class, clA2);
+            assertLoadClassFail(B.class, clA2);
+            assertLoadClassFail(C.class, clA2);
+
+            MockClassLoadingMetaData b1 = new MockClassLoadingMetaData("b", "1.0.0");
+            b1.getRequirements().addRequirement(factory.createRequireModule("a", new VersionRange("1.0.0", "2.0.0")));
+            b1.setPathsAndPackageNames(B.class);
+            KernelControllerContext contextB1 = install(b1);
+            try
+            {
+               ClassLoader clB1 = assertClassLoader(contextB1);
+               assertLoadClass(B.class, clB1);
+               assertLoadClass(A.class, clB1, clA1);
+               assertLoadClassFail(C.class, clB1);
+
+               MockClassLoadingMetaData c1 = new MockClassLoadingMetaData("c", "1.0.0");
+               c1.getRequirements().addRequirement(factory.createRequireModule("b"));
+               c1.getRequirements().addRequirement(factory.createRequireModule("a", new VersionRange("2.0.0", "3.0.0")));
+               c1.setPathsAndPackageNames(C.class);
+               KernelControllerContext contextC1 = install(c1);
+               try
+               {
+                  assertNoClassLoader(contextC1);
+               }
+               finally
+               {
+                  uninstall(contextC1);
+               }
+               assertNoClassLoader(contextC1);
+
+               c1 = new MockClassLoadingMetaData("c", "1.0.0");
+               c1.getRequirements().addRequirement(factory.createRequireModule("b"));
+               c1.getRequirements().addRequirement(factory.createRequireModule("a", new VersionRange("1.0.0", "2.0.0")));
+               c1.setPathsAndPackageNames(C.class);
+               contextC1 = install(c1);
+               try
+               {
+                  ClassLoader clC1 = assertClassLoader(contextC1);
+                  assertLoadClass(C.class, clC1);
+                  assertLoadClass(A.class, clC1, clA1);
+                  assertLoadClass(B.class, clC1, clB1);
+               }
+               finally
+               {
+                  uninstall(contextC1);
+               }
+               assertNoClassLoader(contextC1);
+            }
+            finally
+            {
+               uninstall(contextB1);
+            }
+            assertNoClassLoader(contextB1);
+         }
+         finally
+         {
+            uninstall(contextA2);
+         }
+         assertNoClassLoader(contextA2);
+      }
+      finally
+      {
+         uninstall(contextA1);
+      }
+      assertNoClassLoader(contextA1);
+   }
+}

Added: projects/jboss-cl/trunk/classloading/src/tests/org/jboss/test/classloading/dependency/test/HierarchicalDomainUnitTestCase.java
===================================================================
--- projects/jboss-cl/trunk/classloading/src/tests/org/jboss/test/classloading/dependency/test/HierarchicalDomainUnitTestCase.java	                        (rev 0)
+++ projects/jboss-cl/trunk/classloading/src/tests/org/jboss/test/classloading/dependency/test/HierarchicalDomainUnitTestCase.java	2008-07-10 09:55:12 UTC (rev 75592)
@@ -0,0 +1,470 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2008, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.test.classloading.dependency.test;
+
+import junit.framework.Test;
+
+import org.jboss.classloading.spi.dependency.policy.mock.MockClassLoadingMetaData;
+import org.jboss.classloading.spi.metadata.ClassLoadingMetaDataFactory;
+import org.jboss.kernel.spi.dependency.KernelControllerContext;
+import org.jboss.test.classloading.dependency.support.a.A;
+import org.jboss.test.classloading.dependency.support.b.B;
+
+/**
+ * HierarchicalDomainUnitTestCase.
+ * 
+ * @author <a href="adrian at jboss.com">Adrian Brock</a>
+ * @version $Revision: 1.1 $
+ */
+public class HierarchicalDomainUnitTestCase extends AbstractMockClassLoaderUnitTest
+{
+   public static Test suite()
+   {
+      return suite(HierarchicalDomainUnitTestCase.class);
+   }
+
+   public HierarchicalDomainUnitTestCase(String name)
+   {
+      super(name);
+   }
+   
+   public void testParentFirst() throws Exception
+   {
+      ClassLoadingMetaDataFactory factory = ClassLoadingMetaDataFactory.getInstance();
+      MockClassLoadingMetaData aParent = new MockClassLoadingMetaData("aParent");
+      aParent.setPathsAndPackageNames(A.class);
+      KernelControllerContext contextParentA = install(aParent);
+      try
+      {
+         ClassLoader clParentA = assertClassLoader(contextParentA);
+         assertLoadClass(A.class, clParentA);
+         assertLoadClassFail(B.class, clParentA);
+
+         MockClassLoadingMetaData aChild = new MockClassLoadingMetaData("aChild");
+         aChild.setDomain("ChildDomain");
+         aChild.setJ2seClassLoadingCompliance(true);
+         aChild.setPathsAndPackageNames(A.class);
+         KernelControllerContext contextChildA = install(aChild);
+         try
+         {
+            ClassLoader clChildA = assertClassLoader(contextChildA);
+            assertLoadClass(A.class, clParentA);
+            assertLoadClassFail(B.class, clChildA);
+
+            MockClassLoadingMetaData b = new MockClassLoadingMetaData("b");
+            b.setDomain("ChildDomain");
+            b.setJ2seClassLoadingCompliance(true);
+            b.setPathsAndPackageNames(B.class);
+            b.getRequirements().addRequirement(factory.createRequirePackage(A.class.getPackage().getName()));
+            KernelControllerContext contextB = install(b);
+            try
+            {
+               ClassLoader clB = assertClassLoader(contextB);
+               assertLoadClass(A.class, clParentA);
+               assertLoadClass(B.class, clB);
+            }
+            finally
+            {
+               uninstall(contextB);
+            }
+            assertNoClassLoader(contextB);
+         }
+         finally
+         {
+            uninstall(contextChildA);
+         }
+         assertNoClassLoader(contextChildA);
+      }
+      finally
+      {
+         uninstall(contextParentA);
+      }
+      assertNoClassLoader(contextParentA);
+   }
+   
+   public void testParentLast() throws Exception
+   {
+      ClassLoadingMetaDataFactory factory = ClassLoadingMetaDataFactory.getInstance();
+      MockClassLoadingMetaData aParent = new MockClassLoadingMetaData("aParent");
+      aParent.setPathsAndPackageNames(A.class);
+      KernelControllerContext contextParentA = install(aParent);
+      try
+      {
+         ClassLoader clParentA = assertClassLoader(contextParentA);
+         assertLoadClass(A.class, clParentA);
+         assertLoadClassFail(B.class, clParentA);
+
+         MockClassLoadingMetaData aChild = new MockClassLoadingMetaData("aChild");
+         aChild.setDomain("ChildDomain");
+         aChild.setJ2seClassLoadingCompliance(false);
+         aChild.setPathsAndPackageNames(A.class);
+         KernelControllerContext contextChildA = install(aChild);
+         try
+         {
+            ClassLoader clChildA = assertClassLoader(contextChildA);
+            assertLoadClass(A.class, clChildA);
+            assertLoadClassFail(B.class, clChildA);
+
+            MockClassLoadingMetaData b = new MockClassLoadingMetaData("b");
+            b.setDomain("ChildDomain");
+            b.setJ2seClassLoadingCompliance(false);
+            b.setPathsAndPackageNames(B.class);
+            b.getRequirements().addRequirement(factory.createRequirePackage(A.class.getPackage().getName()));
+            KernelControllerContext contextB = install(b);
+            try
+            {
+               ClassLoader clB = assertClassLoader(contextB);
+               assertLoadClass(A.class, clChildA);
+               assertLoadClass(B.class, clB);
+            }
+            finally
+            {
+               uninstall(contextB);
+            }
+            assertNoClassLoader(contextB);
+         }
+         finally
+         {
+            uninstall(contextChildA);
+         }
+         assertNoClassLoader(contextChildA);
+      }
+      finally
+      {
+         uninstall(contextParentA);
+      }
+      assertNoClassLoader(contextParentA);
+   }
+   
+   public void testParentLastNotInChild() throws Exception
+   {
+      ClassLoadingMetaDataFactory factory = ClassLoadingMetaDataFactory.getInstance();
+      MockClassLoadingMetaData aParent = new MockClassLoadingMetaData("aParent");
+      aParent.setPathsAndPackageNames(A.class);
+      KernelControllerContext contextParentA = install(aParent);
+      try
+      {
+         ClassLoader clParentA = assertClassLoader(contextParentA);
+         assertLoadClass(A.class, clParentA);
+         assertLoadClassFail(B.class, clParentA);
+
+         MockClassLoadingMetaData b = new MockClassLoadingMetaData("b");
+         b.setDomain("ChildDomain");
+         b.setJ2seClassLoadingCompliance(false);
+         b.setPathsAndPackageNames(B.class);
+         b.getRequirements().addRequirement(factory.createRequirePackage(A.class.getPackage().getName()));
+         KernelControllerContext contextB = install(b);
+         try
+         {
+            ClassLoader clB = assertClassLoader(contextB);
+            assertLoadClass(A.class, clParentA);
+            assertLoadClass(B.class, clB);
+         }
+         finally
+         {
+            uninstall(contextB);
+         }
+         assertNoClassLoader(contextB);
+      }
+      finally
+      {
+         uninstall(contextParentA);
+      }
+      assertNoClassLoader(contextParentA);
+   }
+   
+   public void testParentFirstWrongWayAround() throws Exception
+   {
+      ClassLoadingMetaDataFactory factory = ClassLoadingMetaDataFactory.getInstance();
+      MockClassLoadingMetaData b = new MockClassLoadingMetaData("b");
+      b.setDomain("ChildDomain");
+      b.setJ2seClassLoadingCompliance(true);
+      b.setPathsAndPackageNames(B.class);
+      b.getRequirements().addRequirement(factory.createRequirePackage(A.class.getPackage().getName()));
+      KernelControllerContext contextB = install(b);
+      try
+      {
+         assertNoClassLoader(contextB);
+
+         MockClassLoadingMetaData aParent = new MockClassLoadingMetaData("aParent");
+         aParent.setPathsAndPackageNames(A.class);
+         KernelControllerContext contextParentA = install(aParent);
+         try
+         {
+            ClassLoader clParentA = assertClassLoader(contextParentA);
+            assertLoadClass(A.class, clParentA);
+            assertLoadClassFail(B.class, clParentA);
+
+            ClassLoader clB = assertClassLoader(contextB);
+            assertLoadClass(A.class, clParentA);
+            assertLoadClass(B.class, clB);
+         }
+         finally
+         {
+            uninstall(contextParentA);
+         }
+         assertNoClassLoader(contextParentA);
+      }
+      finally
+      {
+         uninstall(contextB);
+      }
+      assertNoClassLoader(contextB);
+   }
+   
+   public void testParentLastWrongWayAround() throws Exception
+   {
+      ClassLoadingMetaDataFactory factory = ClassLoadingMetaDataFactory.getInstance();
+      MockClassLoadingMetaData b = new MockClassLoadingMetaData("b");
+      b.setDomain("ChildDomain");
+      b.setJ2seClassLoadingCompliance(false);
+      b.setPathsAndPackageNames(B.class);
+      b.getRequirements().addRequirement(factory.createRequirePackage(A.class.getPackage().getName()));
+      KernelControllerContext contextB = install(b);
+      try
+      {
+         assertNoClassLoader(contextB);
+
+         MockClassLoadingMetaData aParent = new MockClassLoadingMetaData("aParent");
+         aParent.setPathsAndPackageNames(A.class);
+         KernelControllerContext contextParentA = install(aParent);
+         try
+         {
+            ClassLoader clParentA = assertClassLoader(contextParentA);
+            assertLoadClass(A.class, clParentA);
+            assertLoadClassFail(B.class, clParentA);
+
+            ClassLoader clB = assertClassLoader(contextB);
+            assertLoadClass(A.class, clParentA);
+            assertLoadClass(B.class, clB);
+         }
+         finally
+         {
+            uninstall(contextParentA);
+         }
+         assertNoClassLoader(contextParentA);
+      }
+      finally
+      {
+         uninstall(contextB);
+      }
+      assertNoClassLoader(contextB);
+   }
+   
+   public void testParentRedeploy() throws Exception
+   {
+      ClassLoadingMetaDataFactory factory = ClassLoadingMetaDataFactory.getInstance();
+      MockClassLoadingMetaData b = new MockClassLoadingMetaData("b");
+      b.setDomain("ChildDomain");
+      b.setJ2seClassLoadingCompliance(true);
+      b.setPathsAndPackageNames(B.class);
+      b.getRequirements().addRequirement(factory.createRequirePackage(A.class.getPackage().getName()));
+      KernelControllerContext contextB = install(b);
+      try
+      {
+         assertNoClassLoader(contextB);
+
+         MockClassLoadingMetaData aParent = new MockClassLoadingMetaData("aParent");
+         aParent.setPathsAndPackageNames(A.class);
+         KernelControllerContext contextParentA = install(aParent);
+         try
+         {
+            ClassLoader clParentA = assertClassLoader(contextParentA);
+            assertLoadClass(A.class, clParentA);
+            assertLoadClassFail(B.class, clParentA);
+
+            ClassLoader clB = assertClassLoader(contextB);
+            assertLoadClass(A.class, clParentA);
+            assertLoadClass(B.class, clB);
+         }
+         finally
+         {
+            uninstall(contextParentA);
+         }
+         assertNoClassLoader(contextParentA);
+
+         assertNoClassLoader(contextB);
+
+         contextParentA = install(aParent);
+         try
+         {
+            ClassLoader clParentA = assertClassLoader(contextParentA);
+            assertLoadClass(A.class, clParentA);
+            assertLoadClassFail(B.class, clParentA);
+
+            ClassLoader clB = assertClassLoader(contextB);
+            assertLoadClass(A.class, clParentA);
+            assertLoadClass(B.class, clB);
+         }
+         finally
+         {
+            uninstall(contextParentA);
+         }
+         assertNoClassLoader(contextParentA);
+      }
+      finally
+      {
+         uninstall(contextB);
+      }
+      assertNoClassLoader(contextB);
+   }
+   
+   public void testParentOtherDomain() throws Exception
+   {
+      ClassLoadingMetaDataFactory factory = ClassLoadingMetaDataFactory.getInstance();
+      MockClassLoadingMetaData aParent = new MockClassLoadingMetaData("aParent");
+      aParent.setPathsAndPackageNames(A.class);
+      aParent.setDomain("ParentDomain");
+      KernelControllerContext contextParentA = install(aParent);
+      try
+      {
+         ClassLoader clParentA = assertClassLoader(contextParentA);
+         assertLoadClass(A.class, clParentA);
+         assertLoadClassFail(B.class, clParentA);
+
+         MockClassLoadingMetaData b = new MockClassLoadingMetaData("b");
+         b.setDomain("ChildDomain");
+         b.setParentDomain("ParentDomain");
+         b.setJ2seClassLoadingCompliance(true);
+         b.setPathsAndPackageNames(B.class);
+         b.getRequirements().addRequirement(factory.createRequirePackage(A.class.getPackage().getName()));
+         KernelControllerContext contextB = install(b);
+         try
+         {
+               ClassLoader clB = assertClassLoader(contextB);
+               assertLoadClass(A.class, clParentA);
+               assertLoadClass(B.class, clB);
+         }
+         finally
+         {
+            uninstall(contextB);
+         }
+         assertNoClassLoader(contextB);
+      }
+      finally
+      {
+         uninstall(contextParentA);
+      }
+      assertNoClassLoader(contextParentA);
+   }
+   
+   public void testParentOtherDomainLazy() throws Exception
+   {
+      ClassLoadingMetaDataFactory factory = ClassLoadingMetaDataFactory.getInstance();
+      MockClassLoadingMetaData b = new MockClassLoadingMetaData("b");
+      b.setDomain("ChildDomain");
+      b.setParentDomain("ParentDomain");
+      b.setJ2seClassLoadingCompliance(true);
+      b.setPathsAndPackageNames(B.class);
+      b.getRequirements().addRequirement(factory.createRequirePackage(A.class.getPackage().getName()));
+      KernelControllerContext contextB = install(b);
+      try
+      {
+         assertNoClassLoader(contextB);
+
+         MockClassLoadingMetaData aParent = new MockClassLoadingMetaData("aParent");
+         aParent.setPathsAndPackageNames(A.class);
+         aParent.setDomain("ParentDomain");
+         KernelControllerContext contextParentA = install(aParent);
+         try
+         {
+            ClassLoader clParentA = assertClassLoader(contextParentA);
+            assertLoadClass(A.class, clParentA);
+            assertLoadClassFail(B.class, clParentA);
+
+            ClassLoader clB = assertClassLoader(contextB);
+            assertLoadClass(A.class, clParentA);
+            assertLoadClass(B.class, clB);
+         }
+         finally
+         {
+            uninstall(contextParentA);
+         }
+         assertNoClassLoader(contextParentA);
+      }
+      finally
+      {
+         uninstall(contextB);
+      }
+      assertNoClassLoader(contextB);
+   }
+
+   public void testParentRedeployOtherDomain() throws Exception
+   {
+      ClassLoadingMetaDataFactory factory = ClassLoadingMetaDataFactory.getInstance();
+      MockClassLoadingMetaData b = new MockClassLoadingMetaData("b");
+      b.setDomain("ChildDomain");
+      b.setParentDomain("ParentDomain");
+      b.setJ2seClassLoadingCompliance(true);
+      b.setPathsAndPackageNames(B.class);
+      b.getRequirements().addRequirement(factory.createRequirePackage(A.class.getPackage().getName()));
+      KernelControllerContext contextB = install(b);
+      try
+      {
+         assertNoClassLoader(contextB);
+
+         MockClassLoadingMetaData aParent = new MockClassLoadingMetaData("aParent");
+         aParent.setPathsAndPackageNames(A.class);
+         aParent.setDomain("ParentDomain");
+         KernelControllerContext contextParentA = install(aParent);
+         try
+         {
+            ClassLoader clParentA = assertClassLoader(contextParentA);
+            assertLoadClass(A.class, clParentA);
+            assertLoadClassFail(B.class, clParentA);
+
+            ClassLoader clB = assertClassLoader(contextB);
+            assertLoadClass(A.class, clParentA);
+            assertLoadClass(B.class, clB);
+         }
+         finally
+         {
+            uninstall(contextParentA);
+         }
+         assertNoClassLoader(contextParentA);
+
+         assertNoClassLoader(contextB);
+
+         contextParentA = install(aParent);
+         try
+         {
+            ClassLoader clParentA = assertClassLoader(contextParentA);
+            assertLoadClass(A.class, clParentA);
+            assertLoadClassFail(B.class, clParentA);
+
+            ClassLoader clB = assertClassLoader(contextB);
+            assertLoadClass(A.class, clParentA);
+            assertLoadClass(B.class, clB);
+         }
+         finally
+         {
+            uninstall(contextParentA);
+         }
+         assertNoClassLoader(contextParentA);
+      }
+      finally
+      {
+         uninstall(contextB);
+      }
+      assertNoClassLoader(contextB);
+   }
+}

Modified: projects/jboss-cl/trunk/classloading/src/tests/org/jboss/test/classloading/metadata/test/ModuleRequirementUnitTestCase.java
===================================================================
--- projects/jboss-cl/trunk/classloading/src/tests/org/jboss/test/classloading/metadata/test/ModuleRequirementUnitTestCase.java	2008-07-10 09:41:53 UTC (rev 75591)
+++ projects/jboss-cl/trunk/classloading/src/tests/org/jboss/test/classloading/metadata/test/ModuleRequirementUnitTestCase.java	2008-07-10 09:55:12 UTC (rev 75592)
@@ -24,8 +24,10 @@
 import junit.framework.Test;
 
 import org.jboss.classloading.plugins.metadata.ModuleRequirement;
+import org.jboss.classloading.spi.metadata.Requirement;
 import org.jboss.classloading.spi.version.VersionRange;
 import org.jboss.test.classloading.AbstractClassLoadingTestWithSecurity;
+import org.jboss.test.classloading.metadata.xml.support.TestRequirement;
 
 /**
  * ModuleRequirementUnitTestCase.
@@ -112,7 +114,33 @@
       assertNotNull(test.getName());
       assertEquals(VersionRange.ALL_VERSIONS, test.getVersionRange());
    }
+   
+   public void testIsConsistent() throws Exception
+   {
+      testIsConsistent("a", VersionRange.ALL_VERSIONS, "a", VersionRange.ALL_VERSIONS, true);
+      testIsConsistent("a", VersionRange.ALL_VERSIONS, "a", null, true);
+      testIsConsistent("a", null, "a", VersionRange.ALL_VERSIONS, true);
+
+      testIsConsistent("a", "1.0.0", "2.0.0", "a", "1.0.0", "2.0.0", true);
+      testIsConsistent("a", "1.0.0", "2.0.0", "a", "2.0.0", "2.0.0", true);
+      testIsConsistent("a", "1.0.0", "2.0.0", "a", "1.0.0", "1.0.0", true);
+
+      testIsConsistent("a", "1.0.0", "2.0.0", "b", "1.0.0", "2.0.0", true);
+      testIsConsistent("a", "1.0.0", "2.0.0", "b", "0.0.1", "0.0.1", true);
+      testIsConsistent("a", "1.0.0", "2.0.0", "b", "2.0.1", "2.0.1", true);
+
+      testIsConsistent("a", "1.0.0", "2.0.0", "a", "0.0.1", "0.0.1", false);
+      testIsConsistent("a", "1.0.0", "2.0.0", "a", "2.0.1", "2.0.1", false);
+
+      testIsConsistentOther("a", "1.0.0", "2.0.0", "b", "1.0.0", "2.0.0", true);
+      testIsConsistentOther("a", "1.0.0", "2.0.0", "b", "0.0.1", "0.0.1", true);
+      testIsConsistentOther("a", "1.0.0", "2.0.0", "b", "2.0.1", "2.0.1", true);
+      testIsConsistentOther("a", "1.0.0", "2.0.0", "a", "1.0.0", "2.0.0", true);
+      testIsConsistentOther("a", "1.0.0", "2.0.0", "a", "0.0.1", "0.0.1", true);
+      testIsConsistentOther("a", "1.0.0", "2.0.0", "a", "2.0.1", "2.0.1", true);
       
+   }
+   
    public void testEquals() throws Exception
    {
       testEquals("a", VersionRange.ALL_VERSIONS, "a", VersionRange.ALL_VERSIONS, true);
@@ -148,4 +176,37 @@
          assertFalse("Expected " + test2 + ".equals(" + test1 + ") to be false", test2.equals(test1));
       }
    }
+   
+   protected void testIsConsistent(String name1, String low1, String high1, String name2, String low2, String high2, boolean result)
+   {
+      VersionRange range1 = new VersionRange(low1, true, high1, true);
+      VersionRange range2 = new VersionRange(low2, true, high2, true);
+      testIsConsistent(name1, range1, name2, range2, result);
+      testIsConsistent(name2, range2, name1, range1, result);
+   }
+   
+   protected void testIsConsistentOther(String name1, String low1, String high1, String name2, String low2, String high2, boolean result)
+   {
+      VersionRange range1 = new VersionRange(low1, true, high1, true);
+      VersionRange range2 = new VersionRange(low2, true, high2, true);
+      ModuleRequirement test1 = new ModuleRequirement(name1, range1);
+      TestRequirement test2 = new TestRequirement(name2, range2);
+      testIsConsistent(test1, test2, result);
+      testIsConsistent(test1, test2, result);
+   }
+   
+   protected void testIsConsistent(String name1, VersionRange range1, String name2, VersionRange range2, boolean result)
+   {
+      ModuleRequirement test1 = new ModuleRequirement(name1, range1);
+      ModuleRequirement test2 = new ModuleRequirement(name2, range2);
+      testIsConsistent(test1, test2, result);
+   }
+   
+   protected void testIsConsistent(Requirement test1, Requirement test2, boolean result)
+   {
+      if (result)
+         assertTrue("Expected " + test1 + ".isConsistent(" + test2 + ") to be true", test1.isConsistent(test2));
+      else
+         assertFalse("Expected " + test1 + ".isConsistent(" + test2 + ") to be false", test1.isConsistent(test2));
+   }
 }

Modified: projects/jboss-cl/trunk/classloading/src/tests/org/jboss/test/classloading/metadata/test/PackageRequirementUnitTestCase.java
===================================================================
--- projects/jboss-cl/trunk/classloading/src/tests/org/jboss/test/classloading/metadata/test/PackageRequirementUnitTestCase.java	2008-07-10 09:41:53 UTC (rev 75591)
+++ projects/jboss-cl/trunk/classloading/src/tests/org/jboss/test/classloading/metadata/test/PackageRequirementUnitTestCase.java	2008-07-10 09:55:12 UTC (rev 75592)
@@ -24,8 +24,11 @@
 import junit.framework.Test;
 
 import org.jboss.classloading.plugins.metadata.PackageRequirement;
+import org.jboss.classloading.plugins.metadata.UsesPackageRequirement;
+import org.jboss.classloading.spi.metadata.Requirement;
 import org.jboss.classloading.spi.version.VersionRange;
 import org.jboss.test.classloading.AbstractClassLoadingTestWithSecurity;
+import org.jboss.test.classloading.metadata.xml.support.TestRequirement;
 
 /**
  * PackageRequirementUnitTestCase.
@@ -126,6 +129,82 @@
       testEquals("a", range1, "a", range2, false);
    }
    
+   public void testIsConsistent() throws Exception
+   {
+      testIsConsistent("a", VersionRange.ALL_VERSIONS, "a", VersionRange.ALL_VERSIONS, true);
+      testIsConsistent("a", VersionRange.ALL_VERSIONS, "a", null, true);
+      testIsConsistent("a", null, "a", VersionRange.ALL_VERSIONS, true);
+
+      testIsConsistent("a", "1.0.0", "2.0.0", "a", "1.0.0", "2.0.0", true);
+      testIsConsistent("a", "1.0.0", "2.0.0", "a", "2.0.0", "2.0.0", true);
+      testIsConsistent("a", "1.0.0", "2.0.0", "a", "1.0.0", "1.0.0", true);
+
+      testIsConsistent("a", "1.0.0", "2.0.0", "b", "1.0.0", "2.0.0", true);
+      testIsConsistent("a", "1.0.0", "2.0.0", "b", "0.0.1", "0.0.1", true);
+      testIsConsistent("a", "1.0.0", "2.0.0", "b", "2.0.1", "2.0.1", true);
+
+      testIsConsistent("a", "1.0.0", "2.0.0", "a", "0.0.1", "0.0.1", false);
+      testIsConsistent("a", "1.0.0", "2.0.0", "a", "2.0.1", "2.0.1", false);
+
+      testIsConsistentOther("a", "1.0.0", "2.0.0", "b", "1.0.0", "2.0.0", true);
+      testIsConsistentOther("a", "1.0.0", "2.0.0", "b", "0.0.1", "0.0.1", true);
+      testIsConsistentOther("a", "1.0.0", "2.0.0", "b", "2.0.1", "2.0.1", true);
+      testIsConsistentOther("a", "1.0.0", "2.0.0", "a", "1.0.0", "2.0.0", true);
+      testIsConsistentOther("a", "1.0.0", "2.0.0", "a", "0.0.1", "0.0.1", true);
+      testIsConsistentOther("a", "1.0.0", "2.0.0", "a", "2.0.1", "2.0.1", true);
+
+      testIsConsistentUses("a", "1.0.0", "2.0.0", "b", "1.0.0", "2.0.0", true);
+      testIsConsistentUses("a", "1.0.0", "2.0.0", "b", "0.0.1", "0.0.1", true);
+      testIsConsistentUses("a", "1.0.0", "2.0.0", "b", "2.0.1", "2.0.1", true);
+      testIsConsistentUses("a", "1.0.0", "2.0.0", "a", "1.0.0", "2.0.0", true);
+      testIsConsistentUses("a", "1.0.0", "2.0.0", "a", "0.0.1", "0.0.1", false);
+      testIsConsistentUses("a", "1.0.0", "2.0.0", "a", "2.0.1", "2.0.1", false);
+      
+   }
+   
+   protected void testIsConsistent(String name1, String low1, String high1, String name2, String low2, String high2, boolean result)
+   {
+      VersionRange range1 = new VersionRange(low1, true, high1, true);
+      VersionRange range2 = new VersionRange(low2, true, high2, true);
+      testIsConsistent(name1, range1, name2, range2, result);
+      testIsConsistent(name2, range2, name1, range1, result);
+   }
+   
+   protected void testIsConsistentOther(String name1, String low1, String high1, String name2, String low2, String high2, boolean result)
+   {
+      VersionRange range1 = new VersionRange(low1, true, high1, true);
+      VersionRange range2 = new VersionRange(low2, true, high2, true);
+      PackageRequirement test1 = new PackageRequirement(name1, range1);
+      TestRequirement test2 = new TestRequirement(name2, range2);
+      testIsConsistent(test1, test2, result);
+      testIsConsistent(test1, test2, result);
+   }
+   
+   protected void testIsConsistentUses(String name1, String low1, String high1, String name2, String low2, String high2, boolean result)
+   {
+      VersionRange range1 = new VersionRange(low1, true, high1, true);
+      VersionRange range2 = new VersionRange(low2, true, high2, true);
+      PackageRequirement test1 = new PackageRequirement(name1, range1);
+      UsesPackageRequirement test2 = new UsesPackageRequirement(name2, range2);
+      testIsConsistent(test1, test2, result);
+      testIsConsistent(test1, test2, result);
+   }
+   
+   protected void testIsConsistent(String name1, VersionRange range1, String name2, VersionRange range2, boolean result)
+   {
+      PackageRequirement test1 = new PackageRequirement(name1, range1);
+      PackageRequirement test2 = new PackageRequirement(name2, range2);
+      testIsConsistent(test1, test2, result);
+   }
+   
+   protected void testIsConsistent(Requirement test1, Requirement test2, boolean result)
+   {
+      if (result)
+         assertTrue("Expected " + test1 + ".isConsistent(" + test2 + ") to be true", test1.isConsistent(test2));
+      else
+         assertFalse("Expected " + test1 + ".isConsistent(" + test2 + ") to be false", test1.isConsistent(test2));
+   }
+   
    public void testSerialization() throws Exception
    {
       PackageRequirement test = new PackageRequirement("a", VersionRange.ALL_VERSIONS);

Modified: projects/jboss-cl/trunk/classloading/src/tests/org/jboss/test/classloading/version/test/VersionRangeUnitTestCase.java
===================================================================
--- projects/jboss-cl/trunk/classloading/src/tests/org/jboss/test/classloading/version/test/VersionRangeUnitTestCase.java	2008-07-10 09:41:53 UTC (rev 75591)
+++ projects/jboss-cl/trunk/classloading/src/tests/org/jboss/test/classloading/version/test/VersionRangeUnitTestCase.java	2008-07-10 09:55:12 UTC (rev 75592)
@@ -197,6 +197,36 @@
       testIsInRangeFromString("1.2.3", true, "4.5.6", true, "4.5.6", true);
    }
    
+   public void testIsConsistent() throws Exception
+   {
+      testIsConsistentFromString(null, null, null, null, true);
+      testIsConsistentFromString(null, null, "0.0.0", null, true);
+      testIsConsistentFromString("0.0.0", null, "0.0.0", null, true);
+
+      testIsConsistentFromString(null, null, null, "1.2.3", true);
+      testIsConsistentFromString(null, null, "0.0.0", "1.2.3", true);
+      testIsConsistentFromString("0.0.0", null, "0.0.0", "1.2.3", true);
+      testIsConsistentFromString(null, "1.2.3", "0.0.0", "1.2.3", true);
+      testIsConsistentFromString("0.0.0", "1.2.3", "0.0.0", "1.2.3", true);
+
+      testIsConsistentFromString("1.2.3", "4.5.6", "1.2.3", "4.5.6", true);
+
+      testIsConsistentFromString("1.2.3", "4.5.6", "0.0.0", "1.2.3", false);
+      testIsConsistentFromString("1.2.3", "4.5.6", "4.5.7", "5.0.0", false);
+      
+      testIsConsistentFromStringAllPerms("1.0.0", "2.0.0", "3.0.0", "4.0.0", false);
+      testIsConsistentFromStringAllPerms("1.0.0", "2.0.0", "1.0.1", "1.9.0", true);
+      testIsConsistentFromStringAllPerms("1.0.0", "2.0.0", "1.0.1", "2.0.1", true);
+      testIsConsistentFromStringAllPerms("1.0.0", "2.0.0", "0.9.0", "1.9.0", true);
+      
+      testIsConsistent("1.0.0", true, "2.0.0", false, "1.0.0", true, "2.0.0", false, true);
+      testIsConsistentOneWay("1.0.0", true, "2.0.0", false, "2.0.0", true, "2.0.0", true, false);
+      testIsConsistentOneWay("1.0.0", true, "2.0.0", false, "1.0.0", true, "1.0.0", true, true);
+      testIsConsistentOneWay("1.0.0", false, "2.0.0", false, "1.0.0", true, "1.0.0", true, false);
+      testIsConsistentOneWay("1.0.0", true, "2.0.0", true, "2.0.0", true, "2.0.0", true, true);
+      testIsConsistentOneWay("1.0.0", true, "2.0.0", false, "2.0.0", false, "3.0.0", true, false);
+   }
+   
    public void testSerialization() throws Exception
    {
       VersionRange range = new VersionRange("1.0.0", "2.0.0");;
@@ -444,4 +474,84 @@
       else
          assertFalse("Expected " + range + ".isInRange(" + version + ") to be false", range.isInRange(version));
    }
+   
+   protected void testIsConsistentFromString(String low1, String high1, String low2, String high2, boolean result)
+   {
+      testIsConsistentFromString(low1, false, high1, false, low2, false, high2, false, result);
+   }
+   
+   protected void testIsConsistentFromStringAllPerms(String low1, String high1, String low2, String high2, boolean result)
+   {
+      testIsConsistentFromString(low1, false, high1, false, low2, false, high2, false, result);
+      testIsConsistentFromString(low1, false, high1, false, low2, false, high2, true, result);
+      testIsConsistentFromString(low1, false, high1, false, low2, true, high2, false, result);
+      testIsConsistentFromString(low1, false, high1, false, low2, true, high2, true, result);
+      testIsConsistentFromString(low1, false, high1, true, low2, false, high2, false, result);
+      testIsConsistentFromString(low1, false, high1, true, low2, false, high2, true, result);
+      testIsConsistentFromString(low1, false, high1, true, low2, true, high2, false, result);
+      testIsConsistentFromString(low1, false, high1, true, low2, true, high2, true, result);
+      testIsConsistentFromString(low1, true, high1, false, low2, false, high2, false, result);
+      testIsConsistentFromString(low1, true, high1, false, low2, false, high2, true, result);
+      testIsConsistentFromString(low1, true, high1, false, low2, true, high2, false, result);
+      testIsConsistentFromString(low1, true, high1, false, low2, true, high2, true, result);
+      testIsConsistentFromString(low1, true, high1, true, low2, false, high2, false, result);
+      testIsConsistentFromString(low1, true, high1, true, low2, false, high2, true, result);
+      testIsConsistentFromString(low1, true, high1, true, low2, true, high2, false, result);
+      testIsConsistentFromString(low1, true, high1, true, low2, true, high2, true, result);
+   }
+   
+   protected void testIsConsistentFromString(String low1, boolean lowInclusive1, String high1, boolean highInclusive1, String low2, boolean lowInclusive2, String high2, boolean highInclusive2, boolean result)
+   {
+      testIsConsistent(low1, lowInclusive1, high1, highInclusive1, low2, lowInclusive2, high2, highInclusive2, result);
+
+      Version lowVersion1 = null;
+      if (low1 != null)
+         lowVersion1 = Version.parseVersion(low1);
+      Version highVersion1 = null;
+      if (high1 != null)
+         highVersion1 = Version.parseVersion(high1);
+      Version lowVersion2 = null;
+      if (low2 != null)
+         lowVersion2 = Version.parseVersion(low2);
+      Version highVersion2 = null;
+      if (high2 != null)
+         highVersion2 = Version.parseVersion(high2);
+      testIsConsistent(lowVersion1, lowInclusive1, highVersion1, highInclusive1, lowVersion2, lowInclusive2, highVersion2, highInclusive2, result);
+   }
+   
+   protected void testIsConsistent(Object low1, boolean lowInclusive1, Object high1, boolean highInclusive1, Object low2, boolean lowInclusive2, Object high2, boolean highInclusive2, boolean result)
+   {
+      VersionRange range1 = new VersionRange(low1, lowInclusive1, high1, highInclusive1);
+      VersionRange range2 = new VersionRange(low2, lowInclusive2, high2, highInclusive2);
+      testIsConsistent(range1, range2, result);
+   }
+   
+   protected void testIsConsistentOneWay(Object low1, boolean lowInclusive1, Object high1, boolean highInclusive1, Object low2, boolean lowInclusive2, Object high2, boolean highInclusive2, boolean result)
+   {
+      VersionRange range1 = new VersionRange(low1, lowInclusive1, high1, highInclusive1);
+      VersionRange range2 = new VersionRange(low2, lowInclusive2, high2, highInclusive2);
+      testIsConsistentOneWay(range1, range2, result);
+   }
+   
+   protected void testIsConsistent(VersionRange range1, VersionRange range2, boolean result)
+   {
+      if (result)
+      {
+         assertTrue("Expected " + range1 + ".isConsistent(" + range2 + ") to be true", range1.isConsistent(range2));
+         assertTrue("Expected " + range2 + ".isConsistent(" + range1 + ") to be true", range2.isConsistent(range1));
+      }
+      else
+      {
+         assertFalse("Expected " + range1 + ".isConsistent(" + range2 + ") to be false", range1.isConsistent(range2));
+         assertFalse("Expected " + range2 + ".isConsistent(" + range1 + ") to be false", range2.isConsistent(range1));
+      }
+   }
+   
+   protected void testIsConsistentOneWay(VersionRange range1, VersionRange range2, boolean result)
+   {
+      if (result)
+         assertTrue("Expected " + range1 + ".isConsistent(" + range2 + ") to be true", range1.isConsistent(range2));
+      else
+         assertFalse("Expected " + range1 + ".isConsistent(" + range2 + ") to be false", range1.isConsistent(range2));
+   }
 }




More information about the jboss-cvs-commits mailing list