[jboss-cvs] JBossAS SVN: r99464 - projects/kernel/branches/resolver/dependency/src/main/java/org/jboss/dependency/plugins.

jboss-cvs-commits at lists.jboss.org jboss-cvs-commits at lists.jboss.org
Fri Jan 15 08:06:02 EST 2010


Author: kabir.khan at jboss.com
Date: 2010-01-15 08:06:02 -0500 (Fri, 15 Jan 2010)
New Revision: 99464

Added:
   projects/kernel/branches/resolver/dependency/src/main/java/org/jboss/dependency/plugins/AbstractDependencyResolver.java
   projects/kernel/branches/resolver/dependency/src/main/java/org/jboss/dependency/plugins/DefaultDependencyResolver.java
Modified:
   projects/kernel/branches/resolver/dependency/src/main/java/org/jboss/dependency/plugins/AbstractController.java
Log:
Initial prototype for pluggable resolvers

Modified: projects/kernel/branches/resolver/dependency/src/main/java/org/jboss/dependency/plugins/AbstractController.java
===================================================================
--- projects/kernel/branches/resolver/dependency/src/main/java/org/jboss/dependency/plugins/AbstractController.java	2010-01-15 13:02:04 UTC (rev 99463)
+++ projects/kernel/branches/resolver/dependency/src/main/java/org/jboss/dependency/plugins/AbstractController.java	2010-01-15 13:06:02 UTC (rev 99464)
@@ -24,7 +24,6 @@
 import java.util.Collection;
 import java.util.Collections;
 import java.util.HashSet;
-import java.util.Iterator;
 import java.util.LinkedHashSet;
 import java.util.List;
 import java.util.ListIterator;
@@ -73,6 +72,8 @@
    /** The lock */
    private ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
 
+   AbstractDependencyResolver resolver = new DefaultDependencyResolver(this);
+   
    /**
     * The executor used to install ASYNCHRONOUS contexts. It must have a saturation policy of
     * (or semantically similar to) ThreadPoolExecutor.AbortPolicy or ThreadPoolExecutor.CallerRunsPolicy 
@@ -1057,158 +1058,9 @@
     */
    protected void resolveContexts(boolean trace)
    {
-      boolean wasOnDemandEnabled = false;
-      boolean resolutions = true;
-      while (resolutions || onDemandEnabled)
-      {
-         if (onDemandEnabled)
-            wasOnDemandEnabled = true
-            ;
-         onDemandEnabled = false;
-         resolutions = false;
-         for (ControllerState fromState : stateModel)
-         {
-            ControllerState toState = stateModel.getNextState(fromState);
-            if (resolveContexts(fromState, toState, trace))
-            {
-               resolutions = true;
-               break;
-            }
-         }
-      }
-
-      if (trace)
-      {
-         for (ControllerState state : stateModel)
-         {
-            ControllerState nextState = stateModel.getNextState(state);
-            Set<ControllerContext> stillUnresolved = getContextsByState(state);
-            if (stillUnresolved.isEmpty() == false)
-            {
-               for (ControllerContext ctx : stillUnresolved)
-               {
-                  if (advance(ctx))
-                     log.trace("Still unresolved " + nextState.getStateString() + ": " + ctx);
-               }
-            }
-         }
-      }
-
-      // resolve child controllers
-      for (AbstractController controller : childControllers)
-      {
-         controller.lockWrite();
-         try
-         {
-            controller.resolveContexts(trace);
-         }
-         finally
-         {
-            controller.unlockWrite();
-         }
-      }
-      
-      if (wasOnDemandEnabled)
-      {
-         wasOnDemandEnabled = false;
-         Controller parent = getParentController();
-         if (parent != null)
-         {
-            if (parent instanceof AbstractController == false)
-            {
-               log.warn("Parent is not an instance of AbstractController");
-            }
-            else
-            {
-               ((AbstractController)parent).resolveContexts(trace);
-            }
-         }
-      }
+      resolver.resolveContexts(trace);
    }
 
-   /**
-    * Resolve contexts<p>
-    * <p/>
-    * This method must be invoked with the write lock taken
-    *
-    * @param fromState the from state
-    * @param toState   the to state
-    * @param trace     whether trace is enabled
-    * @return true when there were resolutions
-    */
-   protected boolean resolveContexts(ControllerState fromState, ControllerState toState, boolean trace)
-   {
-      boolean resolutions = false;
-      Set<ControllerContext> unresolved = getContextsByState(fromState);
-      Set<ControllerContext> resolved = resolveContexts(unresolved, fromState, toState, trace);
-      if (resolved.isEmpty() == false)
-      {
-         Set<ControllerContext> toProcess = new HashSet<ControllerContext>();
-         for (ControllerContext context : resolved)
-         {
-            Object name = context.getName();
-            if (fromState.equals(context.getState()) == false)
-            {
-               if (trace)
-                  log.trace("Skipping already installed " + name + " for " + toState.getStateString());
-               installing.remove(context);
-            }
-            else
-            {
-               toProcess.add(context);
-            }
-         }
-         try
-         {
-            if (toProcess.isEmpty() == false)
-            {
-               for (Iterator<ControllerContext> iter = toProcess.iterator(); iter.hasNext(); )
-               {
-                  ControllerContext context = iter.next();
-                  iter.remove();
-                  Object name = context.getName();
-                  try
-                  {
-                     if (fromState.equals(context.getState()) == false)
-                     {
-                        if (trace)
-                           log.trace("Skipping already installed " + name + " for " + toState.getStateString());
-                     }
-                     else
-                     {
-                        if (trace)
-                           log.trace("Dependencies resolved " + name + " for " + toState.getStateString());
-
-                        if (executeOrIncrementStateDirectly(context, trace))
-                        {
-                           resolutions = true;
-                           if (trace)
-                              log.trace(name + " " + toState.getStateString());
-                        }
-                        
-                     }
-                  }
-                  finally
-                  {
-                     installing.remove(context);
-                  }
-               }
-            }
-         }
-         finally
-         {
-            // If we get here something has gone seriously wrong,
-            // but try to tidyup as much state as possible
-            if (toProcess.isEmpty() == false)
-            {
-               for (ControllerContext context : toProcess)
-                  installing.remove(context);
-            }
-         }
-      }
-
-      return resolutions;
-   }
    
    /**
     * Increment state in the current thread, or asynchonously if the context has {@link ControllerMode#ASYNCHRONOUS} and we find an executor<p>
@@ -1219,7 +1071,7 @@
     * @param trace   whether trace is enabled
     * @return whether the increment suceeded. If the context could be incremented asynchronously false is returned
     */
-   private boolean executeOrIncrementStateDirectly(ControllerContext context, boolean trace)
+   protected boolean executeOrIncrementStateDirectly(ControllerContext context, boolean trace)
    {
       boolean asynch = contextsInstalledByExecutor.shouldInstallAsynchronously(context);
       
@@ -1287,90 +1139,6 @@
    }
 
    /**
-    * Resolve contexts<p>
-    * <p/>
-    * This method must be invoked with the write lock taken
-    *
-    * @param contexts the contexts
-    * @param fromState the from state
-    * @param toState   the to state
-    * @param trace    whether trace is enabled
-    * @return the set of resolved contexts
-    */
-   protected Set<ControllerContext> resolveContexts(Set<ControllerContext> contexts, ControllerState fromState, ControllerState toState, boolean trace)
-   {
-      HashSet<ControllerContext> result = new HashSet<ControllerContext>();
-
-      if (contexts.isEmpty() == false)
-      {
-         for (ControllerContext ctx : contexts)
-         {
-            Object name = ctx.getName();
-            if (fromState.equals(ctx.getState()) == false)
-            {
-               if (trace)
-                  log.trace("Skipping already installed " + name + " for " + toState.getStateString());
-            }
-            else if (contextsInstalledByExecutor.isInstalledByOtherThread(ctx))
-            {
-               if (trace)
-                  log.trace("Installed by other thread " + name);
-            }
-            else if (installing.add(ctx) == false)
-            {
-               if (trace)
-                  log.trace("Already installing " + name + " for " + toState.getStateString());
-            }
-            else if (contextsInstalledByExecutor.isBeingInstalled(ctx) == true)
-            {
-               if (trace)
-                  log.trace("Already installing " + name + " for " + toState.getStateString());
-               installing.remove(ctx);
-            }
-            else if (advance(ctx))
-            {
-               try
-               {
-                  if (resolveDependencies(ctx, toState))
-                     result.add(ctx);
-                  else
-                     installing.remove(ctx);
-               }
-               catch (Throwable error)
-               {
-                  installing.remove(ctx);
-                  log.error("Error resolving dependencies for " + toState.getStateString() + ": " + ctx.toShortString(), error);
-                  uninstallContext(ctx, stateModel.getInitialState(), trace);
-                  errorContexts.put(ctx.getName(), ctx);
-                  ctx.setError(error);
-               }
-            }
-            else
-            {
-               installing.remove(ctx);
-            }
-         }
-      }
-
-      return result;
-   }
-   
-   /**
-    * See if the context has its dependencies resolved to move to the given state.
-    * <p/>
-    * This method must be invoked with the write lock taken
-    * 
-    * @param ctx The context
-    * @param state The state we want to move to
-    * @return true if the dependencies are resolved
-    */
-   private boolean resolveDependencies(ControllerContext ctx, ControllerState state)
-   {
-      DependencyInfo dependencies = ctx.getDependencyInfo();
-      return dependencies == null || dependencies.resolveDependencies(this, state);
-   }
-
-   /**
     * Uninstall a context
     * <p/>
     * This method must be invoked with the write lock taken
@@ -2399,7 +2167,7 @@
             {
                try
                {
-                  if (resolveDependencies(context, toState))
+                  if (resolver.resolveDependencies(context, toState))
                   {
                      resolved = true;
                   }
@@ -2579,18 +2347,69 @@
    {
       return registry.getExposedClasses(context);
    }
-
    
    //New accessors for resolver
-   protected boolean isOnDemandEnabled()
+   boolean isOnDemandEnabled()
    {
       return onDemandEnabled;
    }
 
-   protected void setOnDemandEnabled(boolean onDemandEnabled)
+   void setOnDemandEnabled(boolean onDemandEnabled)
    {
       this.onDemandEnabled = onDemandEnabled;
    }
    
+   void setInstalling(ControllerContext context)
+   {
+      installing.add(context);
+   }
    
+   void removeInstalling(ControllerContext context)
+   {
+      installing.remove(context);
+   }
+   
+   boolean checkCanInstall(ControllerContext ctx, ControllerState fromState, ControllerState toState, boolean trace)
+   {
+      if (fromState.equals(ctx.getState()) == false)
+      {
+         if (trace)
+            log.trace("Skipping already installed " + ctx.getName() + " for " + toState.getStateString());
+      }
+      else if (contextsInstalledByExecutor.isInstalledByOtherThread(ctx))
+      {
+         if (trace)
+            log.trace("Installed by other thread " + ctx.getName());
+      }
+      else if (installing.add(ctx) == false)
+      {
+         if (trace)
+            log.trace("Already installing " + ctx.getName() + " for " + toState.getStateString());
+      }
+      else if (contextsInstalledByExecutor.isBeingInstalled(ctx) == true)
+      {
+         if (trace)
+            log.trace("Already installing " + ctx.getName() + " for " + toState.getStateString());
+         installing.remove(ctx);
+      }
+      else if (advance(ctx))
+      {
+         return true;
+      }
+      else
+      {
+         installing.remove(ctx);
+      }
+      return false;
+   }
+   
+   void errorResolvingContext(ControllerContext ctx, ControllerState fromState, ControllerState toState, Throwable error, boolean trace)
+   {
+      installing.remove(ctx);
+      log.error("Error resolving dependencies for " + toState.getStateString() + ": " + ctx.toShortString(), error);
+      uninstallContext(ctx, stateModel.getInitialState(), trace);
+      errorContexts.put(ctx.getName(), ctx);
+      ctx.setError(error);
+      
+   }
 }

Added: projects/kernel/branches/resolver/dependency/src/main/java/org/jboss/dependency/plugins/AbstractDependencyResolver.java
===================================================================
--- projects/kernel/branches/resolver/dependency/src/main/java/org/jboss/dependency/plugins/AbstractDependencyResolver.java	                        (rev 0)
+++ projects/kernel/branches/resolver/dependency/src/main/java/org/jboss/dependency/plugins/AbstractDependencyResolver.java	2010-01-15 13:06:02 UTC (rev 99464)
@@ -0,0 +1,147 @@
+/*
+* JBoss, Home of Professional Open Source.
+* Copyright 2006, 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.dependency.plugins;
+
+import java.util.Set;
+
+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.logging.Logger;
+
+/**
+ * 
+ * @author <a href="kabir.khan at jboss.com">Kabir Khan</a>
+ * @version $Revision: 1.1 $
+ */
+public abstract class AbstractDependencyResolver
+{
+   Logger log = Logger.getLogger(this.getClass());
+   
+   private final AbstractController controller;
+   
+   public AbstractDependencyResolver(Controller controller)
+   {
+      if (controller == null)
+         throw new IllegalArgumentException("Null controller");
+      if (controller instanceof AbstractController == false)
+         throw new IllegalArgumentException("Controller is not an instance of " + AbstractController.class.getName());
+      this.controller = (AbstractController)controller;
+   }
+   
+   protected Controller getController()
+   {
+      return controller;
+   }
+   
+   protected boolean isOnDemandEnabled()
+   {
+      return controller.isOnDemandEnabled();
+   }
+
+   protected void setOnDemandEnabled(boolean onDemandEnabled)
+   {
+      controller.setOnDemandEnabled(onDemandEnabled);
+   }
+
+   protected ControllerStateModel getStateModel()
+   {
+      return controller.getStates();
+   }
+   
+   protected Set<ControllerContext> getContextsByState(ControllerState state)
+   {
+      return controller.getContextsByState(state);
+   }
+   
+   protected boolean advance(ControllerContext context)
+   {
+      return controller.advance(context);
+   }
+   
+   protected Set<AbstractController> getControllers()
+   {
+      return controller.getControllers();
+   }
+   
+   protected void setInstalling(ControllerContext context)
+   {
+      controller.setInstalling(context);
+   }
+   
+   protected void removeInstalling(ControllerContext context)
+   {
+      controller.removeInstalling(context);
+   }
+
+   protected boolean incrementState(ControllerContext context, boolean trace)
+   {
+      return controller.executeOrIncrementStateDirectly(context, trace);
+   }
+   
+   protected boolean checkCanInstall(ControllerContext ctx, ControllerState fromState, ControllerState toState, boolean trace)
+   {
+      return controller.checkCanInstall(ctx, fromState, toState, trace);
+   }
+   
+   protected void errorResolvingContext(ControllerContext ctx, ControllerState fromState, ControllerState toState, Throwable error, boolean trace)
+   {
+      controller.errorResolvingContext(ctx, fromState, toState, error, trace);
+   }
+   
+   protected void resolveChildControllers(boolean trace)
+   {
+      // resolve child controllers
+      for (AbstractController controller : getControllers())
+      {
+         controller.lockWrite();
+         try
+         {
+            controller.resolveContexts(trace);
+         }
+         finally
+         {
+            controller.unlockWrite();
+         }
+      }
+   }
+   
+   protected void resolveParentController(boolean trace)
+   {
+      Controller parent = controller.getParentController();
+      if (parent != null)
+      {
+         if (parent instanceof AbstractController == false)
+         {
+            log.warn("Parent is not an instance of AbstractController");
+         }
+         else
+         {
+            ((AbstractController)parent).resolveContexts(trace);
+         }
+      }
+   }
+   
+   public abstract void resolveContexts(boolean trace);
+   public abstract boolean resolveDependencies(ControllerContext ctx, ControllerState state);
+}

Added: projects/kernel/branches/resolver/dependency/src/main/java/org/jboss/dependency/plugins/DefaultDependencyResolver.java
===================================================================
--- projects/kernel/branches/resolver/dependency/src/main/java/org/jboss/dependency/plugins/DefaultDependencyResolver.java	                        (rev 0)
+++ projects/kernel/branches/resolver/dependency/src/main/java/org/jboss/dependency/plugins/DefaultDependencyResolver.java	2010-01-15 13:06:02 UTC (rev 99464)
@@ -0,0 +1,209 @@
+/*
+* JBoss, Home of Professional Open Source.
+* Copyright 2006, 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.dependency.plugins;
+
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Set;
+
+import org.jboss.dependency.spi.Controller;
+import org.jboss.dependency.spi.ControllerContext;
+import org.jboss.dependency.spi.ControllerState;
+import org.jboss.dependency.spi.DependencyInfo;
+
+/**
+ * 
+ * @author <a href="kabir.khan at jboss.com">Kabir Khan</a>
+ * @version $Revision: 1.1 $
+ */
+public class DefaultDependencyResolver extends AbstractDependencyResolver
+{
+   public DefaultDependencyResolver(Controller controller)
+   {
+      super(controller);
+   }
+
+   /**
+    * Resolve unresolved contexts<p>
+    * <p/>
+    * This method must be invoked with the write lock taken
+    *
+    * @param trace whether trace is enabled
+    */
+   public void resolveContexts(boolean trace)
+   {
+      boolean wasOnDemandEnabled = false;
+      boolean resolutions = true;
+      while (resolutions || isOnDemandEnabled())
+      {
+         if (isOnDemandEnabled())
+            wasOnDemandEnabled = true;
+         
+         setOnDemandEnabled(false);
+         resolutions = false;
+         for (ControllerState fromState : getStateModel())
+         {
+            ControllerState toState = getStateModel().getNextState(fromState);
+            if (resolveContexts(fromState, toState, trace))
+            {
+               resolutions = true;
+               break;
+            }
+         }
+      }
+
+      if (trace)
+      {
+         for (ControllerState state : getStateModel())
+         {
+            ControllerState nextState = getStateModel().getNextState(state);
+            Set<ControllerContext> stillUnresolved = getContextsByState(state);
+            if (stillUnresolved.isEmpty() == false)
+            {
+               for (ControllerContext ctx : stillUnresolved)
+               {
+                  if (advance(ctx))
+                     log.trace("Still unresolved " + nextState.getStateString() + ": " + ctx);
+               }
+            }
+         }
+      }
+
+      // resolve child controllers
+      resolveChildControllers(trace);
+      
+      if (wasOnDemandEnabled)
+      {
+         wasOnDemandEnabled = false;
+         resolveParentController(trace);
+      }
+   }
+
+   protected boolean resolveContexts(ControllerState fromState, ControllerState toState, boolean trace)
+   {
+      boolean resolutions = false;
+      Set<ControllerContext> unresolved = getContextsByState(fromState);
+      Set<ControllerContext> resolved = resolveContexts(unresolved, fromState, toState, trace);
+      if (resolved.isEmpty() == false)
+      {
+         Set<ControllerContext> toProcess = new HashSet<ControllerContext>();
+         for (ControllerContext context : resolved)
+         {
+            Object name = context.getName();
+            if (fromState.equals(context.getState()) == false)
+            {
+               if (trace)
+                  log.trace("Skipping already installed " + name + " for " + toState.getStateString());
+               removeInstalling(context);
+            }
+            else
+            {
+               toProcess.add(context);
+            }
+         }
+         try
+         {
+            if (toProcess.isEmpty() == false)
+            {
+               for (Iterator<ControllerContext> iter = toProcess.iterator(); iter.hasNext(); )
+               {
+                  ControllerContext context = iter.next();
+                  iter.remove();
+                  Object name = context.getName();
+                  try
+                  {
+                     if (fromState.equals(context.getState()) == false)
+                     {
+                        if (trace)
+                           log.trace("Skipping already installed " + name + " for " + toState.getStateString());
+                     }
+                     else
+                     {
+                        if (trace)
+                           log.trace("Dependencies resolved " + name + " for " + toState.getStateString());
+
+                        if (incrementState(context, trace))
+                        {
+                           resolutions = true;
+                           if (trace)
+                              log.trace(name + " " + toState.getStateString());
+                        }
+                        
+                     }
+                  }
+                  finally
+                  {
+                     removeInstalling(context);
+                  }
+               }
+            }
+         }
+         finally
+         {
+            // If we get here something has gone seriously wrong,
+            // but try to tidyup as much state as possible
+            if (toProcess.isEmpty() == false)
+            {
+               for (ControllerContext context : toProcess)
+                  removeInstalling(context);
+            }
+         }
+      }
+
+      return resolutions;
+   }
+
+   protected Set<ControllerContext> resolveContexts(Set<ControllerContext> contexts, ControllerState fromState, ControllerState toState, boolean trace)
+   {
+      HashSet<ControllerContext> result = new HashSet<ControllerContext>();
+
+      if (contexts.isEmpty() == false)
+      {
+         for (ControllerContext ctx : contexts)
+         {
+            if (checkCanInstall(ctx, fromState, toState, trace))
+            {
+               try
+               {
+                  if (resolveDependencies(ctx, toState))
+                     result.add(ctx);
+                  else
+                     removeInstalling(ctx);
+               }
+               catch (Throwable error)
+               {
+                  errorResolvingContext(ctx, fromState, toState, error, trace);
+               }
+            }
+         }
+      }
+
+      return result;
+   }
+
+   public boolean resolveDependencies(ControllerContext ctx, ControllerState state)
+   {
+      DependencyInfo dependencies = ctx.getDependencyInfo();
+      return dependencies == null || dependencies.resolveDependencies(getController(), state);
+   }
+
+}




More information about the jboss-cvs-commits mailing list