[jboss-cvs] JBossAS SVN: r101962 - in projects/kernel/trunk: dependency/src/test/java/org/jboss/test/dependency/controller/support and 2 other directories.

jboss-cvs-commits at lists.jboss.org jboss-cvs-commits at lists.jboss.org
Fri Mar 5 10:37:01 EST 2010


Author: adrian at jboss.org
Date: 2010-03-05 10:37:00 -0500 (Fri, 05 Mar 2010)
New Revision: 101962

Added:
   projects/kernel/trunk/dependency/src/main/java/org/jboss/dependency/plugins/ResolvedState.java
   projects/kernel/trunk/dependency/src/test/java/org/jboss/test/dependency/controller/support/TestSemiResolveDependencyItem.java
   projects/kernel/trunk/dependency/src/test/java/org/jboss/test/dependency/controller/test/SemiResolveDependencyTestCase.java
Modified:
   projects/kernel/trunk/dependency/src/main/java/org/jboss/dependency/plugins/AbstractController.java
   projects/kernel/trunk/dependency/src/main/java/org/jboss/dependency/plugins/AbstractDependencyInfo.java
   projects/kernel/trunk/dependency/src/main/java/org/jboss/dependency/plugins/AbstractDependencyItem.java
   projects/kernel/trunk/dependency/src/main/java/org/jboss/dependency/plugins/TrackingDependencyInfo.java
   projects/kernel/trunk/dependency/src/main/java/org/jboss/dependency/plugins/TrackingDependencyItem.java
   projects/kernel/trunk/dependency/src/test/java/org/jboss/test/dependency/controller/test/ControllerTestSuite.java
   projects/kernel/trunk/jmx-mc-int/src/test/java/org/jboss/test/system/controller/lifecycle/seperated/test/NewOnDemandDependencyTest.java
Log:
[JBKERNEL-108][JBKERNEL-109] - Add support for circular dependencies and fix Undemand processing

Modified: projects/kernel/trunk/dependency/src/main/java/org/jboss/dependency/plugins/AbstractController.java
===================================================================
--- projects/kernel/trunk/dependency/src/main/java/org/jboss/dependency/plugins/AbstractController.java	2010-03-05 15:36:01 UTC (rev 101961)
+++ projects/kernel/trunk/dependency/src/main/java/org/jboss/dependency/plugins/AbstractController.java	2010-03-05 15:37:00 UTC (rev 101962)
@@ -97,6 +97,9 @@
 
    /** The contexts that are currently being resolved/installed */
    private final Set<ControllerContext> installing = new CopyOnWriteArraySet<ControllerContext>();
+
+   /** The contexts that are currently being unresolved/uninstalled */
+   private final Set<ControllerContext> uninstalling = new CopyOnWriteArraySet<ControllerContext>();
    
    /** The contexts that are currently being installed by the executor */
    private final ContextsInstalledByExecutor contextsInstalledByExecutor = new ContextsInstalledByExecutor();
@@ -934,10 +937,22 @@
             resolveContexts(trace);
          else
          {
-            while (stateModel.isAfterState(context.getState(), state))
+            if (uninstalling.add(context))
             {
-               uninstallContext(context, trace);
+               try
+               {
+                  while (stateModel.isAfterState(context.getState(), state))
+                  {
+                     uninstallContext(context, trace);
+                  }
+               }
+               finally
+               {
+                  uninstalling.remove(context);
+               }
             }
+            else if (trace)
+               log.trace("Not uninstalling " + context.getName() + " it is already being uninstalled");
          }
       }
       finally
@@ -1433,19 +1448,32 @@
       if (!stateModel.isValidState(toState))
          log.error("INTERNAL ERROR: unknown state " + toState + " states=" + stateModel, new Exception("STACKTRACE"));
 
-      while (true)
+      if (uninstalling.add(context) == false)
       {
-         ControllerState fromState = context.getState();
-         if (ControllerState.ERROR.equals(fromState))
-            return;
-         if (!stateModel.isValidState(fromState))
-            log.error("INTERNAL ERROR: current state not found: " + context.toShortString(), new Exception("STACKTRACE"));
-         
-         if (stateModel.isAfterState(toState, fromState))
-            return;
-         else
-            uninstallContext(context, trace);
+         if (trace)
+            log.trace("Not uninstalling " + context.getName() + " it is already being uninstalled");
+         return;
       }
+      try
+      {
+         while (true)
+         {
+            ControllerState fromState = context.getState();
+            if (ControllerState.ERROR.equals(fromState))
+               return;
+            if (!stateModel.isValidState(fromState))
+               log.error("INTERNAL ERROR: current state not found: " + context.toShortString(), new Exception("STACKTRACE"));
+            
+            if (stateModel.isAfterState(toState, fromState))
+               return;
+            else
+               uninstallContext(context, trace);
+         }
+      }
+      finally
+      {
+         uninstalling.remove(context);
+      }
    }
 
    /**
@@ -1565,7 +1593,7 @@
          }
          catch (Throwable error)
          {
-            log.error("Error resolving dependencies for " + fromState.getStateString() + ": " + context.toShortString(), error);
+            log.error("Error unresolving dependencies for " + fromState.getStateString() + ": " + context.toShortString(), error);
             // Not much else we can do - no uninstall, since we are at uninstall ;-)
             errorContexts.put(context.getName(), context);
             context.setError(error);
@@ -1660,38 +1688,8 @@
                      continue;
                   
                   Set<DependencyItem> dependsOnOther = otherDependencies.getDependsOnMe(null);
-                  boolean isRequired = false;
-                  for (DependencyItem dependsOnOtherItem : dependsOnOther)
+                  if (dependsOnOther.isEmpty())
                   {
-                     Set<ControllerContext> dependsContexts = CollectionsFactory.createLazySet();
-                     getContexts(dependsOnOtherItem.getName(), dependsContexts);
-                     
-                     if (!dependsContexts.isEmpty())
-                     {
-                        for (ControllerContext dependsContext : dependsContexts)
-                        {
-                           if (dependsContext == null)
-                           {
-                              log.debug("Could not find reverse dependency '" + dependsOnOtherItem.getName() + "' while uninstalling on demand contexts for " + item);
-                              continue;
-                           }
-                           
-                           ControllerState requiredState = item.getWhenRequired();
-                           ControllerState actualState = dependsContext.getState();
-                           
-                           if (requiredState.equals(actualState) || stateModel.isBeforeState(requiredState, actualState))
-                           {
-                              isRequired = true;
-                              break;
-                           }
-                        }
-                     }
-                     
-                     if (isRequired)
-                        break;
-                  }
-                  if (!isRequired)
-                  {
                      //For some reason uninstallContext() uninstalls to the state below the passed in one, add one
                      ControllerState state = stateModel.getNextState(ControllerMode.ON_DEMAND.getRequiredState());
                      uninstallContext(other, state, trace);

Modified: projects/kernel/trunk/dependency/src/main/java/org/jboss/dependency/plugins/AbstractDependencyInfo.java
===================================================================
--- projects/kernel/trunk/dependency/src/main/java/org/jboss/dependency/plugins/AbstractDependencyInfo.java	2010-03-05 15:36:01 UTC (rev 101961)
+++ projects/kernel/trunk/dependency/src/main/java/org/jboss/dependency/plugins/AbstractDependencyInfo.java	2010-03-05 15:37:00 UTC (rev 101962)
@@ -32,7 +32,10 @@
 
 import org.jboss.dependency.spi.CallbackItem;
 import org.jboss.dependency.spi.Controller;
+import org.jboss.dependency.spi.ControllerContext;
 import org.jboss.dependency.spi.ControllerState;
+import org.jboss.dependency.spi.ControllerStateModel;
+import org.jboss.dependency.spi.DependencyInfo;
 import org.jboss.dependency.spi.DependencyItem;
 import org.jboss.dependency.spi.LifecycleCallbackItem;
 import org.jboss.util.JBossObject;
@@ -71,6 +74,9 @@
    
    /** The unresolved dependencies by state */
    private volatile Map<ControllerState, Set<DependencyItem>> unresolved;
+   
+   /** The semiresolved dependencies by state */
+   private volatile Map<ControllerState, Set<DependencyItem>> semiResolved;
 
    /**
     * Create an abstract dependency info
@@ -91,6 +97,13 @@
             if (items != null)
                items.remove(item);
          }
+         Map<ControllerState, Set<DependencyItem>> semiResolved = this.semiResolved;
+         if (semiResolved != null)
+         {
+            Set<DependencyItem> items = semiResolved.get(whenRequired);
+            if (items != null)
+               items.remove(item);
+         }
       }
    }
 
@@ -112,9 +125,163 @@
             unresolved.put(whenRequired, items);
          }
          items.add(item);
+         Map<ControllerState, Set<DependencyItem>> semiResolved = this.semiResolved;
+         if (semiResolved != null)
+         {
+            items = semiResolved.get(whenRequired);
+            if (items != null)
+               items.remove(item);
+         }
       }
    }
 
+   public void semiResolved(DependencyItem item)
+   {
+      if (tracking)
+      {
+         ControllerState whenRequired = item.getWhenRequired();
+         Map<ControllerState, Set<DependencyItem>> semiResolved = this.semiResolved;
+         if (semiResolved == null)
+         {
+            this.semiResolved = new ConcurrentHashMap<ControllerState, Set<DependencyItem>>();
+            semiResolved = this.semiResolved;
+         }
+         Set<DependencyItem> items = semiResolved.get(whenRequired);
+         if (items == null)
+         {
+            items = new ConcurrentSet<DependencyItem>();
+            semiResolved.put(whenRequired, items);
+         }
+         items.add(item);
+         Map<ControllerState, Set<DependencyItem>> unresolved = this.unresolved;
+         if (unresolved != null)
+         {
+            items = unresolved.get(whenRequired);
+            if (items != null)
+               items.remove(item);
+         }
+      }
+   }
+   
+   public ResolvedState semiResolve(TrackingDependencyItem item)
+   {
+      if (item == null)
+         throw new IllegalArgumentException("Null item");
+
+      // Should this be an error?
+      ControllerContext other = item.getSemiResolvedContext();
+      if (other == null)
+         return ResolvedState.UNRESOLVED;
+
+      // Something strange?
+      Controller controller = other.getController();
+      if (controller == null)
+         return ResolvedState.UNRESOLVED;
+      
+      // It is already in the correct state?
+      ControllerState dependentState = item.getDependentState();
+      if (dependentState == null)
+         dependentState = ControllerState.INSTALLED;
+      ControllerStateModel states = controller.getStates();
+      ControllerState otherState = other.getState();
+      if (states.isBeforeState(otherState, dependentState) == false)
+         return ResolvedState.RESOLVED;
+      
+      // Can't do a full semi-resolve
+      if (tracking == false)
+         return ResolvedState.UNRESOLVED;
+      
+      // Can't be semi-resolved if the context is not in the previous state
+      ControllerState previousState = states.getPreviousState(dependentState);
+      if (otherState.equals(previousState) == false)
+         return ResolvedState.UNRESOLVED;
+
+      // It is at least in the semi-resolved state
+      item.setResolved(ResolvedState.SEMI_RESOLVED);
+      
+      // Now check whether the other contexts are transitively semi-resolved
+      Set<ControllerContext> alreadyChecked = new HashSet<ControllerContext>();
+      return checkSemiResolvedIsFullyResolved(other, item.getDependentState(), alreadyChecked);
+   }
+
+   /**
+    * Checks whether the context and its transitive contexts are fully or semi-resolved
+    * 
+    * @param context the context to check
+    * @param dependentState the dependentState of the item
+    * @param alreadyChecked the contexts already checked to avoid recursion
+    * @return the resolved state
+    */
+   private ResolvedState checkSemiResolvedIsFullyResolved(ControllerContext context, ControllerState dependentState, Set<ControllerContext> alreadyChecked)
+   {
+      // Avoid recursion
+      alreadyChecked.add(context);
+
+      // Something strange going on?
+      Controller controller = context.getController();
+      if (controller == null)
+         return ResolvedState.UNRESOLVED;
+      
+      // Work out its state
+      ControllerStateModel states = controller.getStates();
+      ControllerState state = context.getState();
+      
+      // Has it been resolved?
+      if (dependentState == null)
+         dependentState = ControllerState.INSTALLED;
+      if (states.isBeforeState(state, dependentState) == false)
+         return ResolvedState.RESOLVED;
+      
+      // Its not going to move
+      ControllerState nextState = states.getNextState(state);
+      ControllerState requiredState = context.getRequiredState();
+      if (states.isBeforeState(requiredState, nextState))
+         return ResolvedState.SEMI_RESOLVED;
+      
+      DependencyInfo info = context.getDependencyInfo();
+      // No dependencies so we are done
+      if (info == null)
+         return ResolvedState.RESOLVED;
+
+      // It has unresolved dependencies
+      if (info.getUnresolvedDependencies(nextState).isEmpty() == false)
+         return ResolvedState.SEMI_RESOLVED;
+
+      // Its not tracking and no unresolved dependencies so we are done
+      if (info instanceof TrackingDependencyInfo == false)
+         return ResolvedState.RESOLVED;
+      
+      // Now transitively check the semi resolved dependencies
+      TrackingDependencyInfo trackingInfo = (TrackingDependencyInfo) info;
+      Set<DependencyItem> items = trackingInfo.getSemiResolvedDependencies(requiredState);
+      if (items.isEmpty() == false)
+      {
+         for (DependencyItem item : items)
+         {
+            // Shouldn't really happen?
+            if (item instanceof TrackingDependencyItem == false)
+               return ResolvedState.UNRESOLVED;
+            
+            TrackingDependencyItem trackingItem = (TrackingDependencyItem) item;
+            ControllerContext other = trackingItem.getSemiResolvedContext();
+            // This shouldn't really happen either?
+            if (other == null)
+               return ResolvedState.UNRESOLVED;
+            
+            // Only check if we haven't already checked
+            if (alreadyChecked.contains(other) == false)
+            {
+               ResolvedState result = checkSemiResolvedIsFullyResolved(other, item.getDependentState(), alreadyChecked);
+               if (result != ResolvedState.RESOLVED)
+                  return result;
+            }
+         }
+      }
+      
+      // All is good
+      return ResolvedState.RESOLVED;
+   }
+   
    public Set<DependencyItem> getIDependOn(Class<?> type)
    {
       Set<DependencyItem> iDependOn = this.iDependOn;
@@ -175,6 +342,7 @@
             log.debug("Cannot track " + dependency);
             tracking = false;
             unresolved = null;
+            semiResolved = null;
          }
       }
    }
@@ -256,6 +424,18 @@
                resolved = false;
          }
       }
+      if (tracking)
+      {
+         items = getSemiResolvedDependencies(state);
+         if (items.isEmpty() == false)
+         {
+            for (DependencyItem item : items)
+            {
+               if (item.resolve(controller) == false)
+                  resolved = false;
+            }
+         }
+      }
       return resolved;
    }
 
@@ -294,6 +474,27 @@
       return result;
    }
 
+   /**
+    * Get the semi resolved dependencies
+    * 
+    * @param state the state
+    * @return the dependencies or an empty set if there is no state or not tracking dependencies
+    */
+   public Set<DependencyItem> getSemiResolvedDependencies(ControllerState state)
+   {
+      Set<DependencyItem> result = null;
+
+      if (tracking && state != null)
+      {
+         Map<ControllerState, Set<DependencyItem>> semiResolved = this.semiResolved;
+         if (semiResolved != null)
+            result = semiResolved.get(state);
+      }
+      if (result == null)
+         return Collections.emptySet();
+      return result;
+   }
+
    public <T> void addInstallItem(CallbackItem<T> callbackItem)
    {
       Set<CallbackItem<?>> installCallbacks = this.installCallbacks;

Modified: projects/kernel/trunk/dependency/src/main/java/org/jboss/dependency/plugins/AbstractDependencyItem.java
===================================================================
--- projects/kernel/trunk/dependency/src/main/java/org/jboss/dependency/plugins/AbstractDependencyItem.java	2010-03-05 15:36:01 UTC (rev 101961)
+++ projects/kernel/trunk/dependency/src/main/java/org/jboss/dependency/plugins/AbstractDependencyItem.java	2010-03-05 15:37:00 UTC (rev 101962)
@@ -24,6 +24,7 @@
 import org.jboss.dependency.spi.Controller;
 import org.jboss.dependency.spi.ControllerContext;
 import org.jboss.dependency.spi.ControllerState;
+import org.jboss.dependency.spi.ControllerStateModel;
 import org.jboss.dependency.spi.DependencyInfo;
 import org.jboss.logging.Logger;
 import org.jboss.util.JBossObject;
@@ -60,7 +61,10 @@
    private volatile boolean indexedStates; 
    
    /** Whether we are resolved */
-   private volatile boolean resolved;
+   private volatile ResolvedState resolved = ResolvedState.UNRESOLVED;
+   
+   /** Any semi-resolved context */
+   private volatile ControllerContext semiResolvedContext;
 
    /**
     * Create a new dependency item
@@ -114,9 +118,19 @@
 
    public boolean isResolved()
    {
-      return resolved;
+      return resolved == ResolvedState.RESOLVED;
    }
       
+   public ControllerContext getSemiResolvedContext()
+   {
+      return semiResolvedContext;
+   }
+
+   public void setSemiResolvedContext(ControllerContext context)
+   {
+      this.semiResolvedContext = context;
+   }
+
    public boolean resolve(Controller controller)
    {
       indexStates(controller, ControllerState.DESCRIBED, ControllerState.INSTALLED);
@@ -124,7 +138,18 @@
       ControllerState state = dependentState == null ? ControllerState.INSTALLED : dependentState;
       Object iDependOn = getIDependOn();
       ControllerContext context = controller.getContext(iDependOn, state, true);
-      
+      return updateResolved(controller, context);
+   }
+
+   /**
+    * Update the resolved status of this context
+    * 
+    * @param controller the controller 
+    * @param context the context or null if unresolved
+    * @return true when the context is not null
+    */
+   protected boolean updateResolved(Controller controller, ControllerContext context)
+   {
       if (context == null)
       {
          setResolved(false);
@@ -138,6 +163,60 @@
       }
    }
 
+   /**
+    * Update the resolved status of this context
+    * 
+    * @param controller the controller 
+    * @param context the context or null if unresolved
+    * @param the resolved state
+    * @return true when resolved
+    */
+   protected boolean updateResolved(Controller controller, ControllerContext context, ResolvedState resolvedState)
+   {
+      setResolved(resolvedState);
+      if (resolvedState == ResolvedState.RESOLVED)
+      {
+         addDependsOnMe(controller, context);
+         return true;
+      }
+      return false;
+   }
+   
+   /**
+    * Try to semi resolve
+    * 
+    * TODO add on-demand processing to semi resolve
+    * @param controller the controller
+    * @param other the  other context
+    * @return true when fully resolved
+    */
+   protected boolean semiResolve(ControllerContext other)
+   {
+      if (other == null)
+         throw new IllegalArgumentException("Null other");
+
+      Controller controller = other.getController();
+      if (controller == null)
+         return false;
+      
+      indexStates(controller, ControllerState.DESCRIBED, ControllerState.INSTALLED);
+      TrackingDependencyInfo info = this.info;
+      // Can't do a full semiResolve, so just check if it is resolved
+      if (info == null)
+      {
+         // It is already in the correct state?
+         ControllerStateModel states = controller.getStates();
+         ControllerState otherState = other.getState();
+         if (states.isBeforeState(otherState, dependentState))
+            other = null; // Not resolved
+         return updateResolved(controller, other);
+      }
+
+      setSemiResolvedContext(other);
+      ResolvedState resolved = info.semiResolve(this);
+      return updateResolved(controller, other, resolved);
+   }
+
    public void unresolved()
    {
       setResolved(false);
@@ -159,7 +238,10 @@
       ControllerState dependentState = getDependentState();
       if (dependentState != null)
          buffer.append(" dependentState=").append(dependentState.getStateString());
-      buffer.append(" resolved=").append(isResolved());
+      ControllerContext semiResolvedContext = getSemiResolvedContext();
+      if (semiResolvedContext != null)
+         buffer.append(" semi-resolved=" + semiResolvedContext.getName());
+      buffer.append(" resolved=").append(resolved);
    }
    
    public void toShortString(JBossStringBuilder buffer)
@@ -208,26 +290,43 @@
     */
    protected void setResolved(boolean resolved)
    {
-      boolean previous = this.resolved;
+      if (resolved)
+         setResolved(ResolvedState.RESOLVED);
+      else
+         setResolved(ResolvedState.UNRESOLVED);
+   }
+
+   public ResolvedState getResolved()
+   {
+      return resolved;
+   }
+
+   public void setResolved(ResolvedState resolved)
+   {
+      if (resolved == null)
+         throw new IllegalArgumentException("Null resolved");
+      
+      ResolvedState previous = this.resolved;
       this.resolved = resolved;
+      
       if (previous != resolved)
       {
+         // Either resolved or unresolved
+         if (resolved != ResolvedState.SEMI_RESOLVED)
+            setSemiResolvedContext(null); 
          flushJBossObjectCache();
          TrackingDependencyInfo info = this.info;
          if (info != null)
          {
-            if (resolved)
+            if (resolved == ResolvedState.RESOLVED)
                info.resolved(this);
+            else if (resolved == ResolvedState.SEMI_RESOLVED)
+               info.semiResolved(this);
             else
                info.unresolved(this);
          }
          if (log.isTraceEnabled())
-         {
-            if (resolved)
-               log.trace("Resolved " + this);
-            else
-               log.trace("Unresolved " + this);
-         }
+            log.trace(resolved + " " + this);
       }
    }
 

Added: projects/kernel/trunk/dependency/src/main/java/org/jboss/dependency/plugins/ResolvedState.java
===================================================================
--- projects/kernel/trunk/dependency/src/main/java/org/jboss/dependency/plugins/ResolvedState.java	                        (rev 0)
+++ projects/kernel/trunk/dependency/src/main/java/org/jboss/dependency/plugins/ResolvedState.java	2010-03-05 15:37:00 UTC (rev 101962)
@@ -0,0 +1,39 @@
+/*
+* JBoss, Home of Professional Open Source.
+* Copyright 2010, Red Hat Inc., 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.dependency.plugins;
+
+/**
+ * The resolved state
+ *
+ * @author adrian at jboss.org
+ */
+public enum ResolvedState
+{
+   // Unresolved
+   UNRESOLVED,
+   
+   // Semi-resolved
+   SEMI_RESOLVED,
+   
+   // Resolved
+   RESOLVED
+}
\ No newline at end of file

Modified: projects/kernel/trunk/dependency/src/main/java/org/jboss/dependency/plugins/TrackingDependencyInfo.java
===================================================================
--- projects/kernel/trunk/dependency/src/main/java/org/jboss/dependency/plugins/TrackingDependencyInfo.java	2010-03-05 15:36:01 UTC (rev 101961)
+++ projects/kernel/trunk/dependency/src/main/java/org/jboss/dependency/plugins/TrackingDependencyInfo.java	2010-03-05 15:37:00 UTC (rev 101962)
@@ -21,6 +21,9 @@
 */
 package org.jboss.dependency.plugins;
 
+import java.util.Set;
+
+import org.jboss.dependency.spi.ControllerState;
 import org.jboss.dependency.spi.DependencyInfo;
 import org.jboss.dependency.spi.DependencyItem;
 
@@ -44,4 +47,32 @@
     * @param item the item
     */
    void unresolved(DependencyItem item);
+
+   /**
+    * The item is semi resolved
+    * 
+    * @param item the item
+    */
+   void semiResolved(DependencyItem item);
+   
+   /**
+    * Get the semi resolved dependencies for a state
+    * 
+    * @param state the state
+    * @return the semi resolved dependencies
+    */
+   Set<DependencyItem> getSemiResolvedDependencies(ControllerState state);
+   
+   /**
+    * Semi resolve a dependency item<p>
+    * 
+    * Checks whether the dependency can be resolved, if it cannot
+    * puts the dependency in a semi-resolved state. It then
+    * checks whether the semi-resolved context is in the previous
+    * state and it or its transients has no unresolved dependencies.
+    * 
+    * @param item the item
+    * @return the resolved state
+    */
+   ResolvedState semiResolve(TrackingDependencyItem item);
 }

Modified: projects/kernel/trunk/dependency/src/main/java/org/jboss/dependency/plugins/TrackingDependencyItem.java
===================================================================
--- projects/kernel/trunk/dependency/src/main/java/org/jboss/dependency/plugins/TrackingDependencyItem.java	2010-03-05 15:36:01 UTC (rev 101961)
+++ projects/kernel/trunk/dependency/src/main/java/org/jboss/dependency/plugins/TrackingDependencyItem.java	2010-03-05 15:37:00 UTC (rev 101962)
@@ -21,6 +21,7 @@
 */
 package org.jboss.dependency.plugins;
 
+import org.jboss.dependency.spi.ControllerContext;
 import org.jboss.dependency.spi.DependencyItem;
 
 /**
@@ -36,4 +37,32 @@
     * @param info the dependency info
     */
    void setDependencyInfo(TrackingDependencyInfo info);
+
+   /**
+    * Get the resolved state
+    * 
+    * @return the new resolved state
+    */
+   ResolvedState getResolved();
+
+   /**
+    * Set the resolved state
+    * 
+    * @param resolved the new resolved state
+    */
+   void setResolved(ResolvedState resolved);
+
+   /**
+    * Get any semi resolved context
+    * 
+    * @return the semi resolved context or null if not semi resolved
+    */
+   ControllerContext getSemiResolvedContext();
+
+   /**
+    * Set any semi resolved context
+    * 
+    * @param context the semi resolved context or null if not semi resolved
+    */
+   void setSemiResolvedContext(ControllerContext context);
 }

Added: projects/kernel/trunk/dependency/src/test/java/org/jboss/test/dependency/controller/support/TestSemiResolveDependencyItem.java
===================================================================
--- projects/kernel/trunk/dependency/src/test/java/org/jboss/test/dependency/controller/support/TestSemiResolveDependencyItem.java	                        (rev 0)
+++ projects/kernel/trunk/dependency/src/test/java/org/jboss/test/dependency/controller/support/TestSemiResolveDependencyItem.java	2010-03-05 15:37:00 UTC (rev 101962)
@@ -0,0 +1,59 @@
+/*
+* JBoss, Home of Professional Open Source
+* Copyright 2010, Red Hat Inc., 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.dependency.controller.support;
+
+import org.jboss.dependency.plugins.AbstractDependencyItem;
+import org.jboss.dependency.spi.Controller;
+import org.jboss.dependency.spi.ControllerContext;
+import org.jboss.dependency.spi.ControllerState;
+
+/**
+ * TestSemiResolveDependencyItem.
+ * 
+ * @author <a href="adrian at jboss.com">Adrian Brock</a>
+ * @version $Revision: 1.1 $
+ */
+public class TestSemiResolveDependencyItem extends AbstractDependencyItem
+{
+   ControllerContext other;
+   
+   public TestSemiResolveDependencyItem(Object name, String iDependOn, ControllerState whenRequired, ControllerState dependentState)
+   {
+      super(name, iDependOn, whenRequired, dependentState);
+   }
+   
+   public TestSemiResolveDependencyItem(Object name, ControllerContext iDependOn, ControllerState whenRequired, ControllerState dependentState)
+   {
+      super(name, iDependOn.getName(), whenRequired, dependentState);
+      this.other = iDependOn;
+   }
+
+   @Override
+   public boolean resolve(Controller controller)
+   {
+      if (other == null)
+         other = controller.getContext(getIDependOn(), null);
+      if (other == null)
+         return false;
+      return super.semiResolve(other);
+   }
+}

Modified: projects/kernel/trunk/dependency/src/test/java/org/jboss/test/dependency/controller/test/ControllerTestSuite.java
===================================================================
--- projects/kernel/trunk/dependency/src/test/java/org/jboss/test/dependency/controller/test/ControllerTestSuite.java	2010-03-05 15:36:01 UTC (rev 101961)
+++ projects/kernel/trunk/dependency/src/test/java/org/jboss/test/dependency/controller/test/ControllerTestSuite.java	2010-03-05 15:37:00 UTC (rev 101962)
@@ -75,6 +75,7 @@
       suite.addTest(ContextRegistryTestCase.suite());
       suite.addTest(ControllerAsRnQTestCase.suite());
       suite.addTest(ControllerStateTestCase.suite());
+      suite.addTest(SemiResolveDependencyTestCase.suite());
 
       return suite;
    }

Added: projects/kernel/trunk/dependency/src/test/java/org/jboss/test/dependency/controller/test/SemiResolveDependencyTestCase.java
===================================================================
--- projects/kernel/trunk/dependency/src/test/java/org/jboss/test/dependency/controller/test/SemiResolveDependencyTestCase.java	                        (rev 0)
+++ projects/kernel/trunk/dependency/src/test/java/org/jboss/test/dependency/controller/test/SemiResolveDependencyTestCase.java	2010-03-05 15:37:00 UTC (rev 101962)
@@ -0,0 +1,253 @@
+/*
+* JBoss, Home of Professional Open Source
+* Copyright 2010, Red Hat 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.test.dependency.controller.test;
+
+import junit.framework.Test;
+
+import org.jboss.dependency.plugins.AbstractDependencyItem;
+import org.jboss.dependency.spi.ControllerContext;
+import org.jboss.dependency.spi.ControllerMode;
+import org.jboss.dependency.spi.ControllerState;
+import org.jboss.test.dependency.controller.support.TestDelegate;
+import org.jboss.test.dependency.controller.support.TestSemiResolveDependencyItem;
+
+/**
+ * Semi resolve dependency test
+ *
+ * @author adrian at jboss.org
+ */
+public class SemiResolveDependencyTestCase extends AbstractDependencyTest
+{
+   public static Test suite()
+   {
+      return suite(SemiResolveDependencyTestCase.class);
+   }
+   
+   public SemiResolveDependencyTestCase(String name)
+   {
+      super(name);
+   }
+   
+   public void testSmoke() throws Throwable
+   {
+      TestDelegate delegate1 = getDelegate("1");
+      ControllerContext context1 = assertInstall(delegate1);
+
+      TestDelegate delegate2 = getDelegate("2", "1");
+      ControllerContext context2 = assertInstall(delegate2);
+      
+      uninstall(context1);
+      assertContext(context2, ControllerState.PRE_INSTALL);
+      uninstall(context2);
+   }
+   
+   public void testSimpleCircular() throws Throwable
+   {
+      TestDelegate delegate1 = getDelegate("1", "2", ControllerState.INSTALLED);
+      ControllerContext context1 = assertInstall(delegate1, ControllerState.START);
+
+      TestDelegate delegate2 = getDelegate("2", "1", ControllerState.INSTALLED);
+      ControllerContext context2 = assertInstall(delegate2);
+      assertContext(context1, ControllerState.INSTALLED);
+      
+      uninstall(context1);
+      assertContext(context2, ControllerState.START);
+      uninstall(context2);
+   }
+   
+   public void testTransientCircular() throws Throwable
+   {
+      TestDelegate delegate1 = getDelegate("1", "2", ControllerState.INSTALLED);
+      ControllerContext context1 = assertInstall(delegate1, ControllerState.START);
+
+      TestDelegate delegate2 = getDelegate("2", "3", ControllerState.INSTALLED);
+      ControllerContext context2 = assertInstall(delegate2, ControllerState.START);
+      assertContext(context1, ControllerState.START);
+
+      TestDelegate delegate3 = getDelegate("3", "1", ControllerState.INSTALLED);
+      ControllerContext context3 = assertInstall(delegate3);
+      assertContext(context1, ControllerState.INSTALLED);
+      assertContext(context2, ControllerState.INSTALLED);
+      
+      uninstall(context1);
+      assertContext(context2, ControllerState.START);
+      assertContext(context3, ControllerState.START);
+      uninstall(context2);
+      assertContext(context3, ControllerState.START);
+      uninstall(context3);
+   }
+   
+   public void testTransientComplicatedCircular() throws Throwable
+   {
+      TestDelegate delegate1 = getDelegate("1");
+      delegate1.addDependency(createDependency("1", "2", ControllerState.INSTALLED));
+      delegate1.addDependency(createDependency("1", "3", ControllerState.INSTALLED));
+      ControllerContext context1 = assertInstall(delegate1, ControllerState.START);
+
+      TestDelegate delegate2 = getDelegate("2");
+      delegate2.addDependency(createDependency("2", "1", ControllerState.INSTALLED));
+      delegate2.addDependency(createDependency("2", "3", ControllerState.INSTALLED));
+      ControllerContext context2 = assertInstall(delegate2, ControllerState.START);
+      assertContext(context1, ControllerState.START);
+
+      TestDelegate delegate3 = getDelegate("3");
+      delegate3.addDependency(createDependency("3", "1", ControllerState.INSTALLED));
+      delegate3.addDependency(createDependency("3", "2", ControllerState.INSTALLED));
+      ControllerContext context3 = assertInstall(delegate3);
+      assertContext(context1, ControllerState.INSTALLED);
+      assertContext(context2, ControllerState.INSTALLED);
+      
+      uninstall(context1);
+      assertContext(context2, ControllerState.START);
+      assertContext(context3, ControllerState.START);
+      uninstall(context2);
+      assertContext(context3, ControllerState.START);
+      uninstall(context3);
+   }
+   
+   public void testSelfDependency() throws Throwable
+   {
+      TestDelegate delegate1 = getDelegate("1", "1", ControllerState.INSTALLED);
+      ControllerContext context1 = assertInstall(delegate1);
+      uninstall(context1);
+   }
+   
+   public void testNotCircular() throws Throwable
+   {
+      TestDelegate delegate1 = getDelegate("1", "2");
+      ControllerContext context1 = assertInstall(delegate1, ControllerState.PRE_INSTALL);
+
+      TestDelegate delegate2 = getDelegate("2", "1", ControllerState.INSTALLED);
+      ControllerContext context2 = assertInstall(delegate2, ControllerState.START);
+      assertContext(context1, ControllerState.PRE_INSTALL);
+      
+      uninstall(context1);
+      assertContext(context2, ControllerState.START);
+      uninstall(context2);
+   }
+   
+   public void testNotGoingToMove() throws Throwable
+   {
+      TestDelegate delegate1 = getDelegate("1", "2", ControllerState.INSTALLED);
+      delegate1.setMode(ControllerMode.MANUAL);
+      ControllerContext context1 = assertInstall(delegate1, ControllerState.NOT_INSTALLED);
+
+      TestDelegate delegate2 = getDelegate("2", "1", ControllerState.INSTALLED);
+      ControllerContext context2 = assertInstall(delegate2, ControllerState.START);
+      assertContext(context1, ControllerState.NOT_INSTALLED);
+      
+      uninstall(context1);
+      assertContext(context2, ControllerState.START);
+      uninstall(context2);
+   }
+   
+   public void testMoveManual() throws Throwable
+   {
+      TestDelegate delegate1 = getDelegate("1", "2", ControllerState.INSTALLED);
+      delegate1.setMode(ControllerMode.MANUAL);
+      ControllerContext context1 = assertInstall(delegate1, ControllerState.NOT_INSTALLED);
+
+      TestDelegate delegate2 = getDelegate("2", "1", ControllerState.INSTALLED);
+      ControllerContext context2 = assertInstall(delegate2, ControllerState.START);
+      assertContext(context1, ControllerState.NOT_INSTALLED);
+      
+      assertChange(context1, ControllerState.INSTALLED);
+      assertContext(context2, ControllerState.INSTALLED);
+      
+      uninstall(context1);
+      assertContext(context2, ControllerState.START);
+      uninstall(context2);
+   }
+   
+   public void testNormalUnresolvedDependency() throws Throwable
+   {
+      TestDelegate delegate1 = getDelegate("1", "2", ControllerState.INSTALLED);
+      delegate1.addDependency(new AbstractDependencyItem("1", "3", ControllerState.INSTALLED, ControllerState.INSTALLED));
+      ControllerContext context1 = assertInstall(delegate1, ControllerState.START);
+
+      TestDelegate delegate2 = getDelegate("2", "1", ControllerState.INSTALLED);
+      ControllerContext context2 = assertInstall(delegate2, ControllerState.START);
+      assertContext(context1, ControllerState.START);
+
+      TestDelegate delegate3 = getDelegate("3");
+      ControllerContext context3 = assertInstall(delegate3);
+      assertContext(context1, ControllerState.INSTALLED);
+      assertContext(context2, ControllerState.INSTALLED);
+      
+      uninstall(context3);
+      assertContext(context1, ControllerState.START);
+      assertContext(context2, ControllerState.START);
+      
+      uninstall(context1);
+      assertContext(context2, ControllerState.START);
+      uninstall(context2);
+   }
+   
+   protected TestDelegate getDelegate(String name)
+   {
+      return new TestDelegate(name);
+   }
+   
+   protected TestDelegate getDelegate(String name, String other)
+   {
+      return getDelegate(name, other, ControllerState.DESCRIBED);
+   }
+   
+   protected TestDelegate getDelegate(String name, String other, ControllerState whenRequired)
+   {
+      return getDelegate(name, other, whenRequired, ControllerState.INSTALLED);
+   }
+   
+   protected TestDelegate getDelegate(String name, String other, ControllerState whenRequired, ControllerState dependentState)
+   {
+      TestDelegate result = new TestDelegate(name);
+      result.addDependency(createDependency(name, other, whenRequired, dependentState));
+      return result;
+   }
+   
+   protected TestSemiResolveDependencyItem createDependency(String name, String other, ControllerState whenRequired)
+   {
+      return createDependency(name, other, whenRequired, ControllerState.INSTALLED);
+   }
+   
+   protected TestSemiResolveDependencyItem createDependency(String name, String other, ControllerState whenRequired, ControllerState dependentState)
+   {
+      return new TestSemiResolveDependencyItem(name, other, whenRequired, dependentState);
+   }
+   
+   protected TestDelegate getDelegate(String name, ControllerContext other)
+   {
+      return getDelegate(name, other, ControllerState.DESCRIBED);
+   }
+   
+   protected TestDelegate getDelegate(String name, ControllerContext other, ControllerState whenRequired)
+   {
+      return getDelegate(name, other, whenRequired, ControllerState.INSTALLED);
+   }
+   
+   protected TestDelegate getDelegate(String name, ControllerContext other, ControllerState whenRequired, ControllerState dependentState)
+   {
+      TestDelegate result = new TestDelegate(name);
+      result.addDependency(new TestSemiResolveDependencyItem(name, other, whenRequired, dependentState));
+      return result;
+   }
+}

Modified: projects/kernel/trunk/jmx-mc-int/src/test/java/org/jboss/test/system/controller/lifecycle/seperated/test/NewOnDemandDependencyTest.java
===================================================================
--- projects/kernel/trunk/jmx-mc-int/src/test/java/org/jboss/test/system/controller/lifecycle/seperated/test/NewOnDemandDependencyTest.java	2010-03-05 15:36:01 UTC (rev 101961)
+++ projects/kernel/trunk/jmx-mc-int/src/test/java/org/jboss/test/system/controller/lifecycle/seperated/test/NewOnDemandDependencyTest.java	2010-03-05 15:37:00 UTC (rev 101962)
@@ -703,12 +703,12 @@
             
             assertEquals(create1, test1.createOrder);
             assertEquals(start1, test1.startOrder);
-            assertEquals(6, test1.stopOrder);
+            assertEquals(7, test1.stopOrder);
             assertEquals(8, test1.destroyOrder);
             assertEquals(create2, test2.createOrder);
             assertEquals(start2, test2.startOrder);
             assertEquals(5, test2.stopOrder);
-            assertEquals(7, test2.destroyOrder);
+            assertEquals(6, test2.destroyOrder);
             
             mbeans2 = deploy(resourceName2);
 
@@ -746,14 +746,14 @@
                assertServiceDestroyed(NAME_ONE);
                assertEquals(9, test1.createOrder);
                assertEquals(10, test1.startOrder);
-               assertEquals(14, test1.stopOrder);
+               assertEquals(15, test1.stopOrder);
                assertEquals(16, test1.destroyOrder);
                assertNoService(NAME_TWO);
                assertNotRegistered(NAME_TWO);
                assertEquals(11, test2.createOrder);
                assertEquals(12, test2.startOrder);
                assertEquals(13, test2.stopOrder);
-               assertEquals(15, test2.destroyOrder);
+               assertEquals(14, test2.destroyOrder);
             }
          }
       }
@@ -777,7 +777,7 @@
             assertNotRegistered(NAME_ONE);
             assertEquals(9, test1.createOrder);
             assertEquals(10, test1.startOrder);
-            assertEquals(14, test1.stopOrder);
+            assertEquals(15, test1.stopOrder);
             assertEquals(16, test1.destroyOrder);
             assertNoService(NAME_TWO);
             assertNotRegistered(NAME_TWO);
@@ -786,7 +786,7 @@
                assertEquals(11, test2.createOrder);
                assertEquals(12, test2.startOrder);
                assertEquals(13, test2.stopOrder);
-               assertEquals(15, test2.destroyOrder);
+               assertEquals(14, test2.destroyOrder);
             }
          }
       }




More information about the jboss-cvs-commits mailing list