[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