[jboss-cvs] JBossAS SVN: r99462 - in projects/kernel/branches: resolver/dependency/src/main/java/org/jboss/dependency/plugins and 3 other directories.
jboss-cvs-commits at lists.jboss.org
jboss-cvs-commits at lists.jboss.org
Fri Jan 15 07:19:29 EST 2010
Author: kabir.khan at jboss.com
Date: 2010-01-15 07:19:28 -0500 (Fri, 15 Jan 2010)
New Revision: 99462
Added:
projects/kernel/branches/resolver/
projects/kernel/branches/resolver/dependency/src/main/java/org/jboss/dependency/plugins/AbstractController.java
projects/kernel/branches/resolver/kernel/src/test/java/org/jboss/test/kernel/dependency/support/ScopedTestUtil.java
projects/kernel/branches/resolver/kernel/src/test/java/org/jboss/test/kernel/dependency/test/DependencyTestSuite.java
projects/kernel/branches/resolver/kernel/src/test/java/org/jboss/test/kernel/dependency/test/OldAbstractKernelDependencyTest.java
projects/kernel/branches/resolver/kernel/src/test/java/org/jboss/test/kernel/dependency/test/OnDemandDependencyTestCase.java
projects/kernel/branches/resolver/kernel/src/test/java/org/jboss/test/kernel/dependency/test/OnDemandDependencyXMLTestCase.java
projects/kernel/branches/resolver/kernel/src/test/java/org/jboss/test/kernel/dependency/test/ScopedOnDemandDependencyTestCase.java
projects/kernel/branches/resolver/kernel/src/test/java/org/jboss/test/kernel/dependency/test/ScopedOnDemandDependencyXMLTestCase.java
projects/kernel/branches/resolver/kernel/src/test/resources/xml-test/org/jboss/test/kernel/dependency/test/testOnDemandDependencyOnDemandFirst10.xml
projects/kernel/branches/resolver/kernel/src/test/resources/xml-test/org/jboss/test/kernel/dependency/test/testOnDemandDependencyOnDemandFirst11.xml
projects/kernel/branches/resolver/kernel/src/test/resources/xml-test/org/jboss/test/kernel/dependency/test/testOnDemandDependencyOnDemandSecond10.xml
projects/kernel/branches/resolver/kernel/src/test/resources/xml-test/org/jboss/test/kernel/dependency/test/testOnDemandDependencyOnDemandSecond11.xml
projects/kernel/branches/resolver/kernel/src/test/resources/xml-test/org/jboss/test/kernel/dependency/test/testOnDemandDependencyReinstall10.xml
projects/kernel/branches/resolver/kernel/src/test/resources/xml-test/org/jboss/test/kernel/dependency/test/testOnDemandDependencyReinstall11.xml
projects/kernel/branches/resolver/kernel/src/test/resources/xml-test/org/jboss/test/kernel/dependency/test/testOnDemandDependencyReinstall12.xml
Removed:
projects/kernel/branches/resolver/dependency/src/main/java/org/jboss/dependency/plugins/AbstractController.java
projects/kernel/branches/resolver/kernel/src/test/java/org/jboss/test/kernel/dependency/test/DependencyTestSuite.java
projects/kernel/branches/resolver/kernel/src/test/java/org/jboss/test/kernel/dependency/test/OldAbstractKernelDependencyTest.java
projects/kernel/branches/resolver/kernel/src/test/java/org/jboss/test/kernel/dependency/test/OnDemandDependencyTestCase.java
projects/kernel/branches/resolver/kernel/src/test/java/org/jboss/test/kernel/dependency/test/OnDemandDependencyXMLTestCase.java
Log:
Branch to work on the resolvers
Copied: projects/kernel/branches/resolver (from rev 99451, projects/kernel/trunk)
Deleted: projects/kernel/branches/resolver/dependency/src/main/java/org/jboss/dependency/plugins/AbstractController.java
===================================================================
--- projects/kernel/trunk/dependency/src/main/java/org/jboss/dependency/plugins/AbstractController.java 2010-01-15 10:05:32 UTC (rev 99451)
+++ projects/kernel/branches/resolver/dependency/src/main/java/org/jboss/dependency/plugins/AbstractController.java 2010-01-15 12:19:28 UTC (rev 99462)
@@ -1,2541 +0,0 @@
-/*
-* JBoss, Home of Professional Open Source
-* Copyright 2005, JBoss Inc., and individual contributors as indicated
-* by the @authors tag. See the copyright.txt in the distribution for a
-* full listing of individual contributors.
-*
-* This is free software; you can redistribute it and/or modify it
-* under the terms of the GNU Lesser General Public License as
-* published by the Free Software Foundation; either version 2.1 of
-* the License, or (at your option) any later version.
-*
-* This software is distributed in the hope that it will be useful,
-* but WITHOUT ANY WARRANTY; without even the implied warranty of
-* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-* Lesser General Public License for more details.
-*
-* You should have received a copy of the GNU Lesser General Public
-* License along with this software; if not, write to the Free
-* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
-* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
-*/
-package org.jboss.dependency.plugins;
-
-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;
-import java.util.Map;
-import java.util.Set;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.CopyOnWriteArraySet;
-import java.util.concurrent.CountDownLatch;
-import java.util.concurrent.Executor;
-import java.util.concurrent.RejectedExecutionException;
-import java.util.concurrent.locks.ReentrantReadWriteLock;
-
-import org.jboss.dependency.plugins.action.ControllerContextAction;
-import org.jboss.dependency.plugins.action.SimpleControllerContextAction;
-import org.jboss.dependency.plugins.tracker.AbstractContextRegistry;
-import org.jboss.dependency.spi.CallbackItem;
-import org.jboss.dependency.spi.Controller;
-import org.jboss.dependency.spi.ControllerContext;
-import org.jboss.dependency.spi.ControllerContextActions;
-import org.jboss.dependency.spi.ControllerMode;
-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.dependency.spi.asynchronous.AsynchronousController;
-import org.jboss.dependency.spi.graph.GraphController;
-import org.jboss.dependency.spi.graph.LookupStrategy;
-import org.jboss.dependency.spi.graph.SearchInfo;
-import org.jboss.dependency.spi.tracker.ContextFilter;
-import org.jboss.dependency.spi.tracker.ContextQueries;
-import org.jboss.dependency.spi.tracker.ContextRegistry;
-import org.jboss.util.JBossObject;
-import org.jboss.util.collection.CollectionsFactory;
-
-/**
- * Abstract controller.
- *
- * @author <a href="adrian at jboss.com">Adrian Brock</a>
- * @author <a href="ales.justin at jboss.com">Ales Justin</a>
- * @author <a href="kabir.khan at jboss.com">Kabir Khan</a>
- * @version $Revision$
- */
-public class AbstractController extends JBossObject implements Controller, GraphController, AbstractControllerMBean, AsynchronousController, ContextQueries, ContextRegistry
-{
- /** The lock */
- private ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
-
- /**
- * The executor used to install ASYNCHRONOUS contexts. It must have a saturation policy of
- * (or semantically similar to) ThreadPoolExecutor.AbortPolicy or ThreadPoolExecutor.CallerRunsPolicy
- */
- private Executor executor;
-
- /** Whether we are shutdown */
- private boolean shutdown = false;
-
- /** The controller state model */
- private AbstractControllerStateModel stateModel = new MapControllerStateModel();
-
- /** All contexts by name Map<Object, ControllerContext> */
- private Map<Object, ControllerContext> allContexts = new ConcurrentHashMap<Object, ControllerContext>();
-
- /** The contexts by state Map<ControllerState, Set<ControllerContext>> */
- private Map<ControllerState, Set<ControllerContext>> contextsByState = new ConcurrentHashMap<ControllerState, Set<ControllerContext>>();
-
- /** The error contexts Map<Name, ControllerContext> */
- private Map<Object, ControllerContext> errorContexts = new ConcurrentHashMap<Object, ControllerContext>();
-
- /** The contexts that are currently being resolved/installed */
- private Set<ControllerContext> installing = new CopyOnWriteArraySet<ControllerContext>();
-
- /** The contexts that are currently being installed by the executor */
- ContextsInstalledByExecutor contextsInstalledByExecutor = new ContextsInstalledByExecutor();
-
- /** The parent controller */
- private AbstractController parentController;
-
- /** The child controllers */
- private Set<AbstractController> childControllers = new CopyOnWriteArraySet<AbstractController>();
-
- /** The callback items */
- private Map<Object, Set<CallbackItem<?>>> installCallbacks = new ConcurrentHashMap<Object, Set<CallbackItem<?>>>();
- private Map<Object, Set<CallbackItem<?>>> uninstallCallbacks = new ConcurrentHashMap<Object, Set<CallbackItem<?>>>();
-
- /** Whether an on demand context has been enabled */
- private boolean onDemandEnabled = true;
-
- /** Whether stats are enabled */
- private boolean collectStats = false;
-
- /** The install stats */
- private volatile StateStatistics installStats = null;
-
- /** The context tracker */
- private AbstractContextRegistry registry;
-
- /**
- * Create an abstract controller
- */
- public AbstractController()
- {
- addState(ControllerState.NOT_INSTALLED, null);
- addState(ControllerState.PRE_INSTALL, null);
- addState(ControllerState.DESCRIBED, null);
- addState(ControllerState.INSTANTIATED, null);
- addState(ControllerState.CONFIGURED, null);
- addState(ControllerState.CREATE, null);
- addState(ControllerState.START, null);
- addState(ControllerState.INSTALLED, null);
-
- registry = createContextRegistry();
- }
-
- /**
- * Create context registry.
- *
- * @return the context registry
- */
- protected AbstractContextRegistry createContextRegistry()
- {
- return new AbstractContextRegistry(this);
- }
-
- /**
- * Set the executor used to install ASYNCHRONOUS contexts. It must have a saturation policy of
- * (or semantically similar to) ThreadPoolExecutor.AbortPolicy or ThreadPoolExecutor.CallerRunsPolicy.
- *
- * @param executor the executor
- */
- public void setExecutor(Executor executor)
- {
- // TODO - security
- lockWrite();
- try
- {
- this.executor = executor;
- }
- finally
- {
- unlockWrite();
- }
- }
-
- /**
- * Get the executor.
- *
- * @return the executor
- */
- public Executor getExecutor()
- {
- // TODO - security
- return getExecutionEnvironment();
- }
-
- /**
- * Get the executor internal w/o security check.
- *
- * @return the executor
- */
- protected Executor getExecutionEnvironment()
- {
- lockRead();
- try
- {
- return executor;
- }
- finally
- {
- unlockRead();
- }
- }
-
- public boolean isShutdown()
- {
- lockWrite();
- try
- {
- return shutdown;
- }
- finally
- {
- unlockWrite();
- }
- }
-
- /**
- * Check whether the controller is shutdown
- *
- * @throws IllegalStateException when already shutdown
- */
- public void checkShutdown()
- {
- lockWrite();
- try
- {
- if (shutdown)
- throw new IllegalStateException("Already shutdown");
- }
- finally
- {
- unlockWrite();
- }
- }
-
- public void shutdown()
- {
- lockWrite();
- try
- {
- Set<AbstractController> children = getControllers();
- if (children != null && children.isEmpty() == false)
- {
- for (AbstractController child : children)
- {
- try
- {
- child.shutdown();
- }
- catch (Throwable t)
- {
- log.warn("Error during shutdown of child: " + child, t);
- }
- }
- }
-
- Set<ControllerContext> contexts = getAllContexts();
- if (contexts != null && contexts.isEmpty() == false)
- {
- for (ControllerContext context : contexts)
- {
- try
- {
- uninstall(context.getName());
- }
- catch (Throwable t)
- {
- log.warn("Error during shutdown while uninstalling: " + context, t);
- }
- }
- }
- }
- finally
- {
- shutdown = true;
- unlockWrite();
- }
-
- }
-
- /**
- * Get the collectStats.
- *
- * @return the collectStats.
- */
- public boolean isCollectStats()
- {
- return collectStats;
- }
-
- /**
- * Set the collectStats.
- *
- * @param collectStats the collectStats.
- */
- public void setCollectStats(boolean collectStats)
- {
- this.collectStats = collectStats;
- }
-
- public String listStateTimes(boolean details)
- {
- synchronized (this)
- {
- if (installStats == null)
- return "No statistics available";
- return installStats.listTimes(details);
- }
- }
-
- public void addState(ControllerState state, ControllerState before)
- {
- lockWrite();
- try
- {
- if (stateModel.addState(state, before))
- {
- Set<ControllerContext> contexts = new CopyOnWriteArraySet<ControllerContext>();
- contextsByState.put(state, contexts);
- }
- }
- finally
- {
- unlockWrite();
- }
- }
-
- /**
- * Add controller context.
- *
- * This is normally used when switching from top
- * level controller to a scoped one.
- *
- * @param context the controller context
- */
- void addControllerContext(ControllerContext context)
- {
- lockWrite();
- try
- {
- registerControllerContext(context);
- }
- finally
- {
- unlockWrite();
- }
- }
-
- /**
- * Remove controller context.
- *
- * This is normally used when switching from scoped
- * level controller to a top one.
- *
- * @param context the controller context
- */
- void removeControllerContext(ControllerContext context)
- {
- lockWrite();
- try
- {
- unregisterControllerContext(context);
- }
- finally
- {
- unlockWrite();
- }
- }
-
- /**
- * Get the parent controller.
- *
- * @return the parent controller
- */
- public AbstractController getParentController()
- {
- return parentController;
- }
-
- /**
- * Set the parent controller.
- *
- * @param parentController the parent controller
- */
- protected void setParentController(AbstractController parentController)
- {
- this.parentController = parentController;
- }
-
- /**
- * Get child controllers.
- *
- * @return the child controllers
- */
- public Set<AbstractController> getControllers()
- {
- lockRead();
- try
- {
- return Collections.unmodifiableSet(childControllers);
- }
- finally
- {
- unlockRead();
- }
- }
-
- /**
- * Add child controller.
- *
- * @param controller the child controller
- * @return true if equal controller has been already added, see Set.add usage
- */
- public boolean addController(AbstractController controller)
- {
- lockWrite();
- try
- {
- return childControllers.add(controller);
- }
- finally
- {
- unlockWrite();
- }
- }
-
- /**
- * Remove child controller.
- *
- * @param controller the child controller
- * @return true if equal controller was present, see Set.remove usage
- */
- public boolean removeController(AbstractController controller)
- {
- lockWrite();
- try
- {
- return childControllers.remove(controller);
- }
- finally
- {
- unlockWrite();
- }
- }
-
- /**
- * Whether the controller has contexts
- *
- * @return true when there are registered contexts
- */
- public boolean isActive()
- {
- lockRead();
- try
- {
- // is this active
- if (allContexts.isEmpty() == false)
- return true;
-
- // any of the children still active
- for (AbstractController child : getControllers())
- {
- if (child.isActive())
- return true;
- }
-
- return false;
- }
- finally
- {
- unlockRead();
- }
- }
-
- public ControllerContext getContext(Object name, ControllerState state, SearchInfo info)
- {
- if (info == null)
- throw new IllegalArgumentException("Null search info.");
-
- LookupStrategy strategy = info.getStrategy();
- if (strategy == null)
- throw new IllegalArgumentException("AbstractController doesn't implement this search info: " + info);
-
- if (log.isTraceEnabled())
- log.trace("Executing search " + info.getType());
-
- return strategy.getContext(this, name, state);
- }
-
- /**
- * Get all the contexts.
- * In state decending order.
- *
- * @return all contexts
- */
- public Set<ControllerContext> getAllContexts()
- {
- lockRead();
- try
- {
- LinkedHashSet<ControllerContext> result = new LinkedHashSet<ControllerContext>();
- ListIterator<ControllerState> it = stateModel.listIteraror();
- if (it.hasNext())
- {
- result.addAll(getContextsByState(it.next()));
- while (it.hasPrevious())
- {
- result.addAll(getContextsByState(it.previous()));
- }
- }
- result.addAll(errorContexts.values());
- return result;
- }
- finally
- {
- unlockRead();
- }
- }
-
- public ControllerContext getContext(Object name, ControllerState state)
- {
- if (name == null)
- throw new IllegalArgumentException("Null name");
-
- lockRead();
- try
- {
- ControllerContext result = getRegisteredControllerContext(name, false);
- if (result == null && name instanceof Class) // check type matching
- result = getContextByClass((Class<?>)name);
-
- if (result != null && state != null && stateModel.isBeforeState(result.getState(), state))
- {
- return null;
- }
- return result;
- }
- finally
- {
- unlockRead();
- }
- }
-
- public ControllerContext getInstalledContext(Object name)
- {
- return getContext(name, ControllerState.INSTALLED);
- }
-
- public Set<ControllerContext> getNotInstalled()
- {
- lockWrite();
- try
- {
- Set<ControllerContext> result = new HashSet<ControllerContext>(errorContexts.values());
- for (ControllerState state : stateModel)
- {
- if (ControllerState.INSTALLED.equals(state))
- break;
-
- Set<ControllerContext> stateContexts = getContextsByState(state);
- result.addAll(stateContexts);
- }
- return result;
- }
- finally
- {
- unlockWrite();
- }
- }
-
- public ControllerStateModel getStates()
- {
- return stateModel;
- }
-
- public Set<ControllerContext> getContextsByState(ControllerState state)
- {
- return contextsByState.get(state);
- }
-
- public void install(ControllerContext context) throws Throwable
- {
- boolean trace = log.isTraceEnabled();
-
- if (context == null)
- throw new IllegalArgumentException("Null context");
-
- Object name = context.getName();
- if (name == null)
- throw new IllegalArgumentException("Null name " + context.toShortString());
-
- install(context, trace);
- }
-
- public void change(ControllerContext context, ControllerState state) throws Throwable
- {
- boolean trace = log.isTraceEnabled();
-
- if (context == null)
- throw new IllegalArgumentException("Null context");
-
- if (state == null)
- throw new IllegalArgumentException("Null state");
-
- change(context, state, trace);
- }
-
- public void enableOnDemand(ControllerContext context) throws Throwable
- {
- boolean trace = log.isTraceEnabled();
-
- if (context == null)
- throw new IllegalArgumentException("Null context");
-
- enableOnDemand(context, trace);
- }
-
- public ControllerContext uninstall(Object name)
- {
- return uninstall(name, 0);
- }
-
- /**
- * Get controller id - impl detail.
- * It should be unique.
- *
- * @return controller's id
- */
- protected String getId()
- {
- StringBuffer buffer = new StringBuffer();
- buffer.append(getClass().getSimpleName());
- buffer.append("[").append(System.identityHashCode(this)).append("]");
- return buffer.toString();
- }
-
- public void addAlias(Object alias, Object original) throws Throwable
- {
- Map<ControllerState, ControllerContextAction> map = createAliasActions();
- ControllerContextActions actions = new AbstractControllerContextActions(map);
- AliasControllerContext context = new InnerAliasControllerContext(alias, getId(), original, actions);
- preAliasInstall(context);
- install(context);
- // is alias in error
- Throwable error = context.getError();
- if (error != null)
- throw error;
- if (ControllerState.ERROR.equals(context.getState()))
- throw new IllegalArgumentException("Alias " + context + " is in error.");
- }
-
- /**
- * Create alias controller context actions.
- *
- * @return the alias controller context actions
- */
- protected Map<ControllerState, ControllerContextAction> createAliasActions()
- {
- return Collections.<ControllerState, ControllerContextAction>singletonMap(ControllerState.INSTALLED, new AliasControllerContextAction());
- }
-
- /**
- * Apply pre install - e.g. scope key in scoped controller.
- *
- * @param aliasContext the new alias context
- */
- protected void preAliasInstall(ControllerContext aliasContext)
- {
- }
-
- public void removeAlias(Object alias)
- {
- uninstall(alias + "_Alias_" + getId());
- }
-
- /**
- * Uninstall the context.
- *
- * @param name the context name
- * @param level the controller level
- * @return uninstalled controller context
- */
- // todo - some better way to find context's by name
- // currently the first one found is used
- protected ControllerContext uninstall(Object name, int level)
- {
- boolean trace = log.isTraceEnabled();
-
- if (name == null)
- throw new IllegalArgumentException("Null name");
-
- lockWrite();
- try
- {
- if (errorContexts.remove(name) != null && trace)
- log.trace("Tidied up context in error state: " + name);
-
- ControllerContext context = getRegisteredContextAndInterruptAsynchronousInstall(name);
- if (context != null)
- {
- if (trace)
- log.trace("Uninstalling " + context.toShortString());
-
- // get a hold on possible parent before its nullified in uninstall
- AbstractController parent = getParentController();
-
- uninstallContext(context, stateModel.getInitialState(), trace);
-
- try
- {
- unregisterControllerContext(context);
- }
- catch (Throwable t)
- {
- log.warn("Error unregistering context: " + context.toShortString() + " with name: " + name);
- }
-
- while (parent != null)
- {
- try
- {
- parent.unregisterControllerContext(context);
- }
- catch (Throwable t)
- {
- log.warn("Error unregistering context in parent controller: " + context.toShortString() + " with name: " + name);
- }
- parent = parent.getParentController();
- }
- }
- else
- {
- for (AbstractController controller : getControllers())
- {
- context = controller.uninstall(name, level + 1);
- if (context != null)
- break;
- }
- }
- if (context == null && level == 0)
- throw new IllegalStateException("Not installed: " + name);
- return context;
- }
- finally
- {
- unlockWrite();
- }
- }
-
-
- /**
- * Obtains the context, having interrupted its installation process if it is an asynchronous context
- * currently being installed
- * @param name The name of the context
- * @return the context or null if not found
- */
- private ControllerContext getRegisteredContextAndInterruptAsynchronousInstall(Object name)
- {
- ControllerContext context = getRegisteredControllerContext(name, false);
- if (context != null)
- {
- contextsInstalledByExecutor.interruptTaskAndBlock(context, this);
- context = getRegisteredControllerContext(name, false);
- }
- return context;
- }
-
- /**
- * Install a context
- *
- * @param context the context
- * @param trace whether trace is enabled
- * @throws Throwable for any error
- */
- protected void install(ControllerContext context, boolean trace) throws Throwable
- {
- lockWrite();
- try
- {
- checkShutdown();
-
- Object name = context.getName();
-
- // Check the name is not already registered
- if (getRegisteredControllerContext(name, false) != null)
- throw new IllegalStateException(name + " is already installed.");
-
- // Check any alias is not already registered
- Set<Object> aliases = context.getAliases();
- if (aliases != null && aliases.isEmpty() == false)
- {
- for (Object alias : aliases)
- {
- if (getRegisteredControllerContext(alias, false) != null)
- throw new IllegalStateException(alias + " an alias of " + name + " is already installed.");
- }
- }
-
- // set the required state
- ControllerMode mode = context.getMode();
- context.setRequiredState(mode.getRequiredState());
-
- if (trace)
- log.trace("Installing " + context.toShortString());
-
- context.setController(this);
- DependencyInfo dependencies = context.getDependencyInfo();
- if (trace)
- {
- String dependsOn = "[]";
- if (dependencies != null)
- {
- try
- {
- Set<DependencyItem> set = dependencies.getIDependOn(null);
- if (set != null)
- dependsOn = set.toString();
- }
- catch (Throwable t)
- {
- log.warn("Exception getting dependencies: " + t);
- dependsOn = null;
- }
- }
- if (dependsOn != null)
- log.trace("Dependencies for " + name + ": " + dependsOn);
- }
-
- boolean ok = incrementState(context, trace);
- if (ok)
- {
- try
- {
- registerControllerContext(context);
- }
- catch (Throwable t)
- {
- // This is probably unreachable? But let's be paranoid
- ok = false;
- throw t;
- }
- }
- if (ok)
- {
- resolveContexts(trace);
- }
- else
- {
- errorContexts.remove(context);
- throw context.getError();
- }
- }
- finally
- {
- unlockWrite();
- }
- }
-
- /**
- * Change a context's state
- *
- * @param context the context
- * @param state the required state
- * @param trace whether trace is enabled
- * @throws Throwable for any error
- */
- protected void change(ControllerContext context, ControllerState state, boolean trace) throws Throwable
- {
- lockWrite();
- try
- {
- checkShutdown();
-
- if (!stateModel.isValidState(state))
- throw new IllegalArgumentException("Unknown state: " + state);
-
- if (context.getState().equals(state))
- {
- if (trace)
- log.trace("No change required toState=" + state.getStateString() + " " + context.toShortString());
- return;
- }
-
- if (trace)
- log.trace("Change toState=" + state.getStateString() + " " + context.toShortString());
-
- context.setRequiredState(state);
-
- if (stateModel.isBeforeState(context.getState(), state))
- resolveContexts(trace);
- else
- {
- while (stateModel.isAfterState(context.getState(), state))
- {
- uninstallContext(context, trace);
- }
- }
- }
- finally
- {
- unlockWrite();
- }
- }
-
- /**
- * Enable an on demand context
- *
- * @param context the context
- * @param trace whether trace is enabled
- * @throws Throwable for any error
- */
- protected void enableOnDemand(ControllerContext context, boolean trace) throws Throwable
- {
- lockWrite();
- try
- {
- checkShutdown();
-
- if (ControllerMode.ON_DEMAND.equals(context.getMode()) == false)
- throw new IllegalStateException("Context is not ON DEMAND: " + context.toShortString());
-
- // Sanity check
- getRegisteredControllerContext(context.getName(), true);
-
- // Already done
- if (ControllerState.INSTALLED.equals(context.getRequiredState()))
- return;
- context.setRequiredState(ControllerState.INSTALLED);
-
- if (trace)
- log.trace("Enable onDemand: " + context.toShortString());
-
- onDemandEnabled = true;
- }
- finally
- {
- unlockWrite();
- }
- }
-
- /**
- * Increment state<p>
- * <p/>
- * This method must be invoked with the write lock taken.
- *
- * @param context the context
- * @param trace whether trace is enabled
- * @return whether the suceeded
- */
- protected boolean incrementState(ControllerContext context, boolean trace)
- {
- ControllerState fromState = context.getState();
-
- Controller fromController = context.getController();
- Set<ControllerContext> fromContexts;
-
- ControllerState toState;
- if (ControllerState.ERROR.equals(fromState))
- {
- ControllerState initialState = stateModel.getInitialState();
- errorContexts.remove(context);
- Throwable error = null;
- unlockWrite();
- try
- {
- install(context, ControllerState.ERROR, initialState);
- }
- catch (Throwable t)
- {
- error = t;
- }
- finally
- {
- lockWrite();
- if (error != null)
- {
- log.error("Error during initial installation: " + context.toShortString(), error);
- context.setError(error);
- errorContexts.put(context.getName(), context);
- return false;
- }
- }
- Set<ControllerContext> notInstalled = fromController.getContextsByState(initialState);
- notInstalled.add(context);
- context.setState(initialState);
- return true;
- }
- else
- {
- fromContexts = fromController.getContextsByState(fromState);
- if (fromContexts.contains(context) == false)
- throw new IllegalStateException("Context not found in previous state (" + fromState + "): " + context.toShortString());
- toState = stateModel.getNextState(fromState);
- if (toState == null)
- throw new IllegalStateException("No state after " + fromState);
- }
-
- unlockWrite();
- Throwable error = null;
- try
- {
- install(context, fromState, toState);
-
- if (fromContexts != null)
- fromContexts.remove(context);
- Controller toController = context.getController();
- Set<ControllerContext> toContexts = toController.getContextsByState(toState);
- toContexts.add(context);
- context.setState(toState);
-
- handleInstallLifecycleCallbacks(context, toState);
- resolveCallbacks(context, toState, true);
- }
- catch (Throwable t)
- {
- error = t;
- }
- finally
- {
- lockWrite();
- if (error != null)
- {
- log.error("Error installing to " + toState.getStateString() + ": " + context.toShortString(), error);
- uninstallContext(context, stateModel.getInitialState(), trace);
- errorContexts.put(context.getName(), context);
- context.setError(error);
- return false;
- }
- }
-
- return true;
- }
-
- /**
- * Resolve unresolved contexts<p>
- * <p/>
- * This method must be invoked with the write lock taken
- *
- * @param trace whether trace is enabled
- */
- protected void resolveContexts(boolean trace)
- {
- boolean resolutions = true;
- while (resolutions || onDemandEnabled)
- {
- 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();
- }
- }
- }
-
- /**
- * 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>
- * <p/>
- * This method must be invoked with the write lock taken.
- *
- * @param context the context
- * @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)
- {
- boolean asynch = contextsInstalledByExecutor.shouldInstallAsynchronously(context);
-
- if (asynch)
- {
- if (executor == null)
- {
- Object ctx = trace ? context : context.getName();
- log.warn("No executor in controller " + this + " to use installing asynchronous context " + ctx);
-
- }
-
- Executor foundExecutor = searchForExecutor();
- if (foundExecutor != null)
- {
- InstallControllerContextTask task = new InstallControllerContextTask(context, trace);
- contextsInstalledByExecutor.markForTaskExecution(context, task);
-
- if (trace)
- log.trace("Recorded for asynchronous installation " + context.getName());
-
- try
- {
- foundExecutor.execute(task);
- return false;
- }
- catch(RejectedExecutionException e)
- {
- Object ctx = trace ? context : context.getName();
- log.warn("Asynchronous execution rejected by executor for context " + ctx + ":" + e.getMessage());
- contextsInstalledByExecutor.disassociateWithTask(context);
- }
- }
- }
-
- return incrementState(context, trace);
- }
-
- /**
- * Return the executor stored in this controller or in its parent hierarchy. The nearest executor is returned.
- * <p/>
- * This method must be called with the write or read lock taken
- * @return The found executor
- */
- protected Executor searchForExecutor()
- {
- if (executor != null)
- {
- return executor;
- }
- AbstractController parent = getParentController();
- if (parent != null)
- {
- try
- {
- parent.lockRead();
- return parent.searchForExecutor();
- }
- finally
- {
- parent.unlockRead();
- }
- }
- return null;
- }
-
- /**
- * 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
- *
- * @param context the context to uninstall
- * @param toState the target state
- * @param trace whether trace is enabled
- */
- protected void uninstallContext(ControllerContext context, ControllerState toState, boolean trace)
- {
- if (!stateModel.isValidState(toState))
- log.error("INTERNAL ERROR: unknown state " + toState + " states=" + stateModel, new Exception("STACKTRACE"));
-
- 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);
- }
- }
-
- /**
- * Uninstall a context<p>
- * <p/>
- * This method must be invoked with the write lock taken
- *
- * @param context the context to uninstall
- * @param trace whether trace is enabled
- */
- protected void uninstallContext(ControllerContext context, boolean trace)
- {
- Object name = context.getName();
-
- ControllerState fromState = context.getState();
-
- if (trace)
- log.trace("Uninstalling " + name + " from " + fromState.getStateString());
-
- Controller fromController = context.getController();
-
- Set<ControllerContext> fromContexts = fromController.getContextsByState(fromState);
- if (fromContexts == null || fromContexts.remove(context) == false)
- throw new Error("INTERNAL ERROR: context not found in previous state " + fromState.getStateString() + " context=" + context.toShortString(), new Exception("STACKTRACE"));
-
- DependencyInfo dependencies = context.getDependencyInfo();
- if (dependencies != null)
- {
- try
- {
- Set<DependencyItem> dependsOnMe = dependencies.getDependsOnMe(null);
- if (dependsOnMe.isEmpty() == false)
- {
- for (DependencyItem item : dependsOnMe)
- {
- if (item.isResolved())
- {
- ControllerState dependentState = item.getDependentState();
- if (dependentState == null || dependentState.equals(fromState))
- {
- if (item.unresolved(this))
- {
- Set<ControllerContext> dependents = CollectionsFactory.createLazySet();
- getContexts(item.getName(), dependents);
- if (dependents.isEmpty() == false)
- {
- ControllerState whenRequired = item.getWhenRequired();
- if (whenRequired == null)
- whenRequired = stateModel.getInitialState();
-
- for (ControllerContext dependent : dependents)
- {
- boolean selfDependency = (dependent == context);
- if (!selfDependency)
- {
- contextsInstalledByExecutor.interruptTaskAndBlock(dependent, this);
- if (stateModel.isBeforeState(dependent.getState(), whenRequired) == false)
- {
- uninstallContext(dependent, whenRequired, trace);
- }
- }
- }
- }
- }
- }
- }
- }
- }
- }
- catch (Throwable error)
- {
- log.error("Error resolving 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);
- }
- }
-
- // The state could have changed while calling out to dependents
- fromState = context.getState();
- if (ControllerState.ERROR.equals(fromState))
- return;
-
- ControllerState toState = stateModel.getPreviousState(fromState);
- if (toState == null)
- {
- // This is hack, we signal true uninstalled status by putting it in the error state
- context.setState(ControllerState.ERROR);
- return;
- }
-
- unlockWrite();
- try
- {
- resolveCallbacks(context, fromState, false);
- handleUninstallLifecycleCallbacks(context, toState);
-
- uninstall(context, fromState, toState);
-
- Controller toController = context.getController();
- Set<ControllerContext> toContexts = toController.getContextsByState(toState);
- toContexts.add(context);
- context.setState(toState);
-
- uninstallUnusedOnDemandContexts(context, trace);
- }
- catch (Throwable t)
- {
- log.warn("Error uninstalling from " + fromState.getStateString() + ": " + context.toShortString(), t);
- }
- finally
- {
- lockWrite();
- }
- }
-
- /**
- * If the context being uninstalled depends on On_Demand contexts that are not used anymore
- * those On_Demand contexts are uninstalled back to the DESCRIBED state.<p>
- *
- * This method must be called with NO locks taken.
- *
- * @param context the context which is being uninstalled.
- * @param trace do trace log
- */
- protected void uninstallUnusedOnDemandContexts(ControllerContext context, boolean trace)
- {
- lockWrite();
- try
- {
- DependencyInfo dependencies = context.getDependencyInfo();
- if (dependencies != null)
- {
- Set<DependencyItem> iDependOn = dependencies.getIDependOn(null);
- if (iDependOn.isEmpty() == false)
- {
- for (DependencyItem item : iDependOn)
- {
- if (item.isResolved()) //TODO Is this check necessary
- {
- Object name = item.getIDependOn();
- if (name == null)
- continue;
-
- ControllerContext other = getContext(name, null);
- if (other == null)
- {
- log.warn("Could not find dependency while uninstalling on demand contexts for " + item);
- continue;
- }
- if (other.getMode() != ControllerMode.ON_DEMAND)
- continue;
-
- DependencyInfo otherDependencies = other.getDependencyInfo();
- if (otherDependencies == null)
- continue;
-
- Set<DependencyItem> dependsOnOther = otherDependencies.getDependsOnMe(null);
- boolean isRequired = false;
- for (DependencyItem dependsOnOtherItem : dependsOnOther)
- {
- ControllerContext dependsContext = getContext(dependsOnOtherItem.getName(), null);
- if (dependsContext == null)
- {
- log.warn("Could not find dependency 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)
- {
- //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);
- }
- }
- }
- }
- }
- }
- finally
- {
- unlockWrite();
- }
- }
-
- /**
- * Get all contexts by name,
- * check child controllers as well.
- *
- * @param name the name of the context
- * @param contexts found contexts
- */
- protected void getContexts(Object name, Set<ControllerContext> contexts)
- {
- ControllerContext context = getContext(name, null);
- if (context != null)
- {
- Set<Object> aliases = context.getAliases();
- // only pick up unique name
- // TODO also ignore alises from @Aliases?
- if (aliases == null || aliases.contains(name) == false)
- contexts.add(context);
- }
-
- Set<AbstractController> children = getControllers();
- if (children != null && children.isEmpty() == false)
- {
- for (AbstractController child : children)
- {
- child.getContexts(name, contexts);
- }
- }
- }
-
- /**
- * Add callback item under demand name.
- *
- * @param <T> the callback item type
- * @param name demand name
- * @param isInstallPhase install or uninstall phase
- * @param callback callback item
- */
- protected <T> void addCallback(Object name, boolean isInstallPhase, CallbackItem<T> callback)
- {
- lockWrite();
- try
- {
- Map<Object, Set<CallbackItem<?>>> map = (isInstallPhase ? installCallbacks : uninstallCallbacks);
- Set<CallbackItem<?>> callbacks = map.get(name);
- if (callbacks == null)
- {
- callbacks = new HashSet<CallbackItem<?>>();
- map.put(name, callbacks);
- }
- callbacks.add(callback);
- }
- finally
- {
- unlockWrite();
- }
- }
-
- /**
- * Remove callback item under demand name.
- *
- * @param <T> the callback item type
- * @param name demand name
- * @param isInstallPhase install or uninstall phase
- * @param callback callback item
- */
- protected <T> void removeCallback(Object name, boolean isInstallPhase, CallbackItem<T> callback)
- {
- lockWrite();
- try
- {
- Map<Object, Set<CallbackItem<?>>> map = (isInstallPhase ? installCallbacks : uninstallCallbacks);
- Set<CallbackItem<?>> callbacks = map.get(name);
- if (callbacks != null)
- {
- callbacks.remove(callback);
- if (callbacks.isEmpty())
- map.remove(name);
- }
- }
- finally
- {
- unlockWrite();
- }
- }
-
- /**
- * Get calbacks from context.
- *
- * @param context current context
- * @param isInstallPhase install or uninstall phase
- * @return callback items from dependency info
- */
- protected Set<CallbackItem<?>> getDependencyCallbacks(ControllerContext context, boolean isInstallPhase)
- {
- DependencyInfo di = context.getDependencyInfo();
- if (di != null)
- {
- return isInstallPhase ? di.getInstallItems() : di.getUninstallItems();
- }
- return null;
- }
-
- /**
- * Get the matching callbacks.
- *
- * @param name demand name
- * @param isInstallPhase install or uninstall phase
- * @return all matching registered callbacks or empty set if no such item
- */
- protected Set<CallbackItem<?>> getCallbacks(Object name, boolean isInstallPhase)
- {
- lockRead();
- try
- {
- Map<Object, Set<CallbackItem<?>>> map = (isInstallPhase ? installCallbacks : uninstallCallbacks);
- Set<CallbackItem<?>> callbacks = map.get(name);
- return callbacks != null ? callbacks : Collections.<CallbackItem<?>>emptySet();
- }
- finally
- {
- unlockRead();
- }
- }
-
- /**
- * Resolve callbacks.
- *
- * @param callbacks the callbacks
- * @param state current context state
- * @param execute do execute callback
- * @param isInstallPhase install or uninstall phase
- * @param type install or uninstall type
- */
- protected void resolveCallbacks(Set<CallbackItem<?>> callbacks, ControllerState state, boolean execute, boolean isInstallPhase, boolean type)
- {
- if (callbacks != null && callbacks.isEmpty() == false)
- {
- for (CallbackItem<?> callback : callbacks)
- {
- if (callback.getWhenRequired().equals(state))
- {
- if (isInstallPhase)
- {
- addCallback(callback.getIDependOn(), type, callback);
- }
- else
- {
- removeCallback(callback.getIDependOn(), type, callback);
- }
- if (execute)
- {
- try
- {
- callback.ownerCallback(this, isInstallPhase);
- }
- catch (Throwable t)
- {
- log.warn("Broken callback: " + callback, t);
- }
- }
- }
- }
- }
- }
-
- /**
- * Resolve callback items.
- *
- * @param context current context
- * @param state current context state
- * @param isInstallPhase install or uninstall phase
- */
- protected void resolveCallbacks(ControllerContext context, ControllerState state, boolean isInstallPhase)
- {
- ClassLoader previous = null;
- try
- {
- previous = SecurityActions.setContextClassLoader(context);
- // existing owner callbacks
- Set<CallbackItem<?>> installs = getDependencyCallbacks(context, true);
- resolveCallbacks(installs, state, isInstallPhase, isInstallPhase, true);
- Set<CallbackItem<?>> uninstalls = getDependencyCallbacks(context, false);
- resolveCallbacks(uninstalls, state, isInstallPhase == false, isInstallPhase, false);
-
- // change callbacks, applied only if context is autowire candidate
- DependencyInfo dependencyInfo = context.getDependencyInfo();
- if (dependencyInfo != null && dependencyInfo.isAutowireCandidate())
- {
- // match callbacks by name
- Set<CallbackItem<?>> existingCallbacks = new HashSet<CallbackItem<?>>();
- existingCallbacks.addAll(getCallbacks(context.getName(), isInstallPhase));
- // match by classes
- Collection<Class<?>> classes = getExposedClasses(context);
- if (classes != null && classes.isEmpty() == false)
- {
- for (Class<?> clazz : classes)
- {
- existingCallbacks.addAll(getCallbacks(clazz, isInstallPhase));
- }
- }
-
- // Do the installs if we are at the required state
- if (existingCallbacks != null && existingCallbacks.isEmpty() == false)
- {
- for(CallbackItem<?> callback : existingCallbacks)
- {
- if (state.equals(callback.getDependentState()))
- {
- try
- {
- callback.changeCallback(this, context, isInstallPhase);
- }
- catch (Throwable t)
- {
- log.warn("Broken callback: " + callback, t);
- }
- }
- }
- }
- }
- }
- // let's make sure we suppress any exceptions
- catch (Throwable t)
- {
- log.warn("Cannot resolve callbacks, state= " + state + ", isInstall= " + isInstallPhase + ", context= " + context, t);
- }
- finally
- {
- if (previous != null)
- SecurityActions.resetContextClassLoader(previous);
- }
- }
-
- /**
- * Handle install lifecycle callbacks.
- *
- * @param context the context
- * @param state the state
- * @throws Throwable for any error
- */
- protected void handleInstallLifecycleCallbacks(ControllerContext context, ControllerState state) throws Throwable
- {
- handleLifecycleCallbacks(context, state, true);
- }
-
- /**
- * Handle uninstall lifecycle callbacks.
- *
- * @param context the context
- * @param state the state
- * @throws Throwable for any error
- */
- protected void handleUninstallLifecycleCallbacks(ControllerContext context, ControllerState state) throws Throwable
- {
- ControllerState oldState = stateModel.getNextState(state);
- handleLifecycleCallbacks(context, oldState, false);
- }
-
- /**
- * Handle lifecycle callbacks.
- *
- * @param context the context
- * @param state the state
- * @param install is it install or uninstall
- * @throws Throwable for any error
- */
- protected void handleLifecycleCallbacks(ControllerContext context, ControllerState state, boolean install) throws Throwable
- {
- DependencyInfo di = context.getDependencyInfo();
- if (di != null)
- {
- List<LifecycleCallbackItem> callbacks = di.getLifecycleCallbacks();
- for (LifecycleCallbackItem callback : callbacks)
- {
- if (callback.getWhenRequired().equals(state))
- {
- if (install)
- callback.install(context);
- else
- callback.uninstall(context);
- }
- }
- }
- }
-
- /**
- * Install a context<p>
- * <p/>
- * This method must be invoked with NO locks taken
- *
- * @param context the context
- * @param fromState the from state
- * @param toState the toState
- * @throws Throwable for any error
- */
- protected void install(ControllerContext context, ControllerState fromState, ControllerState toState) throws Throwable
- {
- long time = 0;
- boolean collectStats = this.collectStats;
- if (collectStats)
- time = System.currentTimeMillis();
- try
- {
- context.install(fromState, toState);
- }
- finally
- {
- if (collectStats)
- {
- time = System.currentTimeMillis() - time;
- if (time > 0)
- {
- synchronized (this)
- {
- if (installStats == null)
- installStats = new StateStatistics();
-
- String state = toState.getStateString();
- String name = context.getName().toString();
- installStats.addStatistic(state, name, time);
- }
- }
- }
- }
- }
-
- /**
- * Uninstall a context<p>
- * <p/>
- * This method must be invoked with NO locks taken
- *
- * @param context the context
- * @param fromState the from state
- * @param toState the to state
- */
- protected void uninstall(ControllerContext context, ControllerState fromState, ControllerState toState)
- {
- context.uninstall(fromState, toState);
- }
-
- /**
- * Whether we should advance the context<p>
- * <p/>
- * This method must be invoked with the write lock taken
- *
- * @param context the context
- * @return true when we should advance the context
- */
- protected boolean advance(ControllerContext context)
- {
- ControllerMode mode = context.getMode();
-
- // Never advance for disabled
- if (ControllerMode.DISABLED.equals(mode))
- return false;
-
- return stateModel.isBeforeState(context.getState(), context.getRequiredState());
- }
-
- /**
- * Lock for read
- */
- protected void lockRead()
- {
- lock.readLock().lock();
- }
-
- /**
- * Unlock for read
- */
- protected void unlockRead()
- {
- lock.readLock().unlock();
- }
-
- /**
- * Lock for write
- */
- protected void lockWrite()
- {
- lock.writeLock().lock();
- }
-
- /**
- * Unlock for write
- */
- protected void unlockWrite()
- {
- lock.writeLock().unlock();
- }
-
- /**
- * Get a registered context<p>
- * <p/>
- * This method should be invoked with at least the read lock taken
- *
- * @param name the name with which to register it
- * @param mustExist whether to throw an error when the context does not exist
- * @return context the registered context
- * @throws IllegalArgumentException for null parameters
- * @throws IllegalStateException if the context if must exist is true and the context does not exist
- */
- protected ControllerContext getRegisteredControllerContext(Object name, boolean mustExist)
- {
- if (name == null)
- throw new IllegalArgumentException("Null name");
-
- ControllerContext result = allContexts.get(name);
- if (mustExist && result == null)
- throw new IllegalStateException("Context does not exist with name: " + name);
- return result;
- }
-
- /**
- * Register a context and all its aliases<p>
- * <p/>
- * This method must be invoked with the write lock taken
- *
- * @param context the context to register
- * @throws IllegalArgumentException for null parameters
- * @throws IllegalStateException if the context is already registered with that name or alias
- */
- protected void registerControllerContext(ControllerContext context)
- {
- if (context == null)
- throw new IllegalArgumentException("Null context");
-
- Set<Object> aliases = context.getAliases();
-
- // Register the context
- Object name = context.getName();
- registerControllerContext(name, context);
-
- // Register the aliases
- if (aliases != null && aliases.isEmpty() == false)
- {
- int ok = 0;
- try
- {
- for (Object alias : aliases)
- {
- registerControllerContext(alias, context);
- ++ok;
- }
- }
- finally
- {
- // It didn't work
- if (ok != aliases.size() && ok > 0)
- {
- // Unregister the aliases we added
- for (Object alias : aliases)
- {
- if (ok-- == 0)
- break;
- try
- {
- unregisterControllerContext(alias);
- }
- catch (Throwable ignored)
- {
- log.debug("Error unregistering alias: " + alias, ignored);
- }
- }
-
- // Unregister the context
- try
- {
- unregisterControllerContext(name);
- }
- catch (Throwable ignored)
- {
- log.debug("Error unregistering context with name: " + name, ignored);
- }
- }
- }
- }
- }
-
- /**
- * Unregister a context and all its aliases<p>
- * <p/>
- * This method must be invoked with the write lock taken
- *
- * @param context the context
- * @throws IllegalArgumentException for null parameters
- * @throws IllegalStateException if the context is not registered
- */
- protected void unregisterControllerContext(ControllerContext context)
- {
- if (context == null)
- throw new IllegalArgumentException("Null context");
-
- Set<Object> aliases = context.getAliases();
-
- // Unregister the context
- Object name = context.getName();
- unregisterControllerContext(name);
-
- // Unegister the aliases
- if (aliases != null && aliases.isEmpty() == false)
- {
- for (Object alias : aliases)
- {
- try
- {
- unregisterControllerContext(alias);
- }
- catch (Throwable ignored)
- {
- log.debug("Error unregistering alias: " + alias, ignored);
- }
- }
- }
- }
-
- /**
- * Register a context<p>
- * <p/>
- * This method must be invoked with the write lock taken<p>
- * <p/>
- * NOTE: You probably want to use the {@link #registerControllerContext(ControllerContext)}
- *
- * @param name the name with which to register it
- * @param context the context to register
- * @throws IllegalArgumentException for null parameters
- * @throws IllegalStateException if the context is already registered with that name
- */
- protected void registerControllerContext(Object name, ControllerContext context)
- {
- if (name == null)
- throw new IllegalArgumentException("Null name");
- if (context == null)
- throw new IllegalArgumentException("Null context");
-
- if (allContexts.containsKey(name) == false)
- allContexts.put(name, context);
- else
- throw new IllegalStateException("Unable to register context " + context.toShortString() + ", name already exists: " + name);
- }
-
- /**
- * Unregister a context<p>
- * <p/>
- * This method must be invoked with the write lock taken<p>
- * <p/>
- * NOTE: You probably want to use the {@link #unregisterControllerContext(ControllerContext)}
- *
- * @param name the name it was registered with
- * @throws IllegalArgumentException for null parameters
- */
- protected void unregisterControllerContext(Object name)
- {
- if (name == null)
- throw new IllegalArgumentException("Null name");
- allContexts.remove(name);
- }
-
- // --- alias dependency
-
- private static class InnerAliasControllerContext extends AbstractAliasControllerContext
- {
- private InnerAliasControllerContext(Object alias, String id, Object original, ControllerContextActions actions)
- {
- super(alias, id, original, actions);
- }
- }
-
- private class AliasControllerContextAction extends SimpleControllerContextAction<AliasControllerContext>
- {
- protected AliasControllerContext contextCast(ControllerContext context)
- {
- return AliasControllerContext.class.cast(context);
- }
-
- protected boolean validateContext(ControllerContext context)
- {
- return (context instanceof AliasControllerContext);
- }
-
- protected void installAction(AliasControllerContext context) throws Throwable
- {
- Object alias = context.getAlias();
- Object jmxAlias = JMXObjectNameFix.needsAnAlias(alias);
- if (jmxAlias != null)
- alias = jmxAlias;
-
- Object original = context.getOriginal();
- Object jmxOriginal = JMXObjectNameFix.needsAnAlias(original);
- if (jmxOriginal != null)
- original = jmxOriginal;
-
- // get the context's controller - not the one we registered with
- AbstractController controller = (AbstractController)context.getController();
- lockWrite();
- try
- {
- ControllerContext lookup = controller.getRegisteredControllerContext(original, true);
- controller.registerControllerContext(alias, lookup);
- if (log.isTraceEnabled())
- log.trace("Added alias " + alias + " for context " + context);
- }
- finally
- {
- unlockWrite();
- }
- }
-
- protected void uninstallAction(AliasControllerContext context)
- {
- lockWrite();
- try
- {
- Object alias = context.getAlias();
- Object jmxAlias = JMXObjectNameFix.needsAnAlias(alias);
- if (jmxAlias != null)
- alias = jmxAlias;
-
- // get the context's controller - not the one we registered with
- AbstractController controller = (AbstractController)context.getController();
- controller.unregisterControllerContext(alias);
- if (log.isTraceEnabled())
- log.trace("Removed alias " + alias);
- }
- finally
- {
- unlockWrite();
- }
- }
- }
-
- public boolean isAsynchronousInstallInProgress(ControllerContext context)
- {
- if (context.getMode() != ControllerMode.ASYNCHRONOUS)
- return false;
-
- return contextsInstalledByExecutor.isBeingInstalled(context);
- }
-
- /**
- * A task being handled asyynchronously by the executor
- *
- */
- abstract class InterruptibleControllerTask implements Runnable
- {
- /**
- * The thread used to handle the asynchronous task
- */
- Thread thread;
-
- /**
- * True if the task is interrupted
- */
- volatile boolean interrupted;
-
- /**
- * Latch counted down by interrupted tasks once they have reached a state where they finish
- */
- CountDownLatch interruptedLatch;
-
- /**
- * Gets the thread that is currently used to install the asyncronous task
- * @return The thread, or null if still queued in the executor
- */
- synchronized Thread getThread()
- {
- return thread;
- }
-
- /**
- * Interrupt the task, and if associated with a thread
- * return a countdown latch that will have a count of 0
- * once the job has broken out
- * @return the latch or null if not yet interrupted
- */
- synchronized CountDownLatch interrupt()
- {
- interrupted = true;
- if (thread != null)
- {
- interruptedLatch = new CountDownLatch(1);
- return interruptedLatch;
- }
- return null;
- }
-
- /**
- * Check the interrupted status
- * @return true if interrupted
- */
- boolean isInterrupted()
- {
- return interrupted;
- }
-
- /**
- * Associate the current thread with the task, or clear it in contextsInstalledByExecutor
- * if it has been interrupted. This should be the first thing tasks do once they run.
- *
- * @param context the context
- * @return true if interrupted
- */
- synchronized boolean associateWithThreadOrDisassociateIfInterrupted(ControllerContext context)
- {
- if (interrupted)
- {
- contextsInstalledByExecutor.disassociateWithTask(context);
- return true;
- }
- thread = Thread.currentThread();
- return false;
- }
-
- /**
- * Disassociate the thread with the task, and if interrupted count down the latch so those
- * awaiting the latch know the task has finished.
- */
- synchronized void disassociateWithThreadAndSignalEnd()
- {
- thread = null;
- if (interruptedLatch != null)
- {
- interruptedLatch.countDown();
- }
- }
- }
-
-
- /**
- * Interruptible task used to install a controller context asynchronously.
- * It will install the context as far as possible towards its required state,
- * before resolving the other contexts.
- */
- class InstallControllerContextTask extends InterruptibleControllerTask
- {
- ControllerContext context;
- ClassLoader classLoader;
- boolean trace;
-
- public InstallControllerContextTask(ControllerContext context, boolean trace)
- {
- this.context = context;
- this.classLoader = SecurityActions.getContextClassLoader();
- this.trace = trace;
- }
-
- public void run()
- {
- if (associateWithThreadOrDisassociateIfInterrupted(context))
- return;
-
- if (trace)
- log.trace(Thread.currentThread().getName() + " starting asyncronous install of " + context.getName());
-
- lockWrite();
- ClassLoader tcl = SecurityActions.setContextClassLoader(classLoader);
- try
- {
- //Move the given context as far through the states as possible
- boolean stateChanged = false;
- try
- {
- stateChanged = installMyContext();
- }
- finally
- {
- contextsInstalledByExecutor.disassociateWithTask(context);
- }
-
- //The given context had its state changed, now see if anybody was dependent on it
- if (stateChanged && !interrupted)
- {
- resolveContexts(trace);
- }
- }
- catch (Throwable t)
- {
- Object ctx = trace ? context : context.getName();
- log.error("Problem installing context asynchronously " + ctx, t);
- }
- finally
- {
- if (trace)
- log.trace(Thread.currentThread().getName() + " asynchronous install done for " + context.getName());
- SecurityActions.resetContextClassLoader(tcl);
- unlockWrite();
-
- disassociateWithThreadAndSignalEnd();
- }
- }
-
- boolean installMyContext()
- {
- boolean stateChanged = false;
-
- if (!stateModel.isValidState(context.getRequiredState()))
- throw new IllegalArgumentException("Unknown state: " + context.getRequiredState());
-
- boolean resolved = true;
-
- while(resolved && stateModel.isBeforeState(context.getState(), context.getRequiredState()) && !interrupted)
- {
- resolved = false;
- ControllerState toState = stateModel.getNextState(context.getState());
- if (advance(context))
- {
- try
- {
- if (resolveDependencies(context, toState))
- {
- resolved = true;
- }
- }
- catch (Throwable error)
- {
- Object ctx = trace ? context : context.getName();
- log.error("Error resolving dependencies for " + toState.getStateString() + ": " + ctx, error);
- uninstallContext(context, stateModel.getInitialState(), trace);
- errorContexts.put(context.getName(), context);
- context.setError(error);
- }
-
- if (resolved)
- {
- resolved = incrementState(context, trace);
- if (resolved)
- {
- stateChanged = true;
- }
- }
- }
- }
-
- return stateChanged;
- }
- }
-
-
-
- /**
- * Class used to keep track of contexts that are scheduled for asynchronous install,
- * or are in the process of being installed asynchronously.
- *
- */
- private static class ContextsInstalledByExecutor
- {
- /** The contexts that are currently being installed by the executor */
- Map<ControllerContext, InterruptibleControllerTask> executorTasksByContext = new ConcurrentHashMap<ControllerContext, InterruptibleControllerTask>();
- /**
- * Checks whether context should be installed asynchronously, by checking the controller mode and the current thread
- * @param context The context
- * @return Whether the context should be installed in the executor
- */
- boolean shouldInstallAsynchronously(ControllerContext context)
- {
- if (context.getMode() == ControllerMode.ASYNCHRONOUS)
- {
- final InterruptibleControllerTask task = executorTasksByContext.get(context);
- return task == null || task.getThread() != Thread.currentThread();
- }
- return false;
- }
-
- /**
- * Records the context and the asynchronous task to install it
- * @param context The context to be installed asynchronously
- * @param task The task that will be used to install the context
- */
- void markForTaskExecution(ControllerContext context, InterruptibleControllerTask task)
- {
- executorTasksByContext.put(context, task);
- }
-
- /**
- * Removes the task that was used to install the context
- * @param context The context whose task we want to remove
- */
- void disassociateWithTask(ControllerContext context)
- {
- executorTasksByContext.remove(context);
- }
-
- /**
- * Checks if the context is recorded for asynchronous install, and if the thread used is different
- * from the current thread.
- * @param context The context to check
- * @return true if installed by another thread
- */
- boolean isInstalledByOtherThread(ControllerContext context)
- {
- final InterruptibleControllerTask task = executorTasksByContext.get(context);
- return task != null && Thread.currentThread() != task.getThread();
- }
-
- /**
- * Checks in the context is recorded for asynchronous install
- * @param context The context to check
- * @return true if recorded for asynchronous install
- */
- boolean isBeingInstalled(ControllerContext context)
- {
- return executorTasksByContext.get(context) != null;
- }
-
- /**
- * Checks if the passed in context is recorded for asynchronous install,
- * and if it is interrupts the asynchronous task.<p>
- *
- * This method must be called with the write lock taken
- *
- * @param context The context to interrupt
- * @param controller the controller
- */
- void interruptTaskAndBlock(ControllerContext context, AbstractController controller)
- {
- InterruptibleControllerTask task = executorTasksByContext.get(context);
- if (task != null)
- {
- controller.unlockWrite();
- try
- {
- CountDownLatch latch = task.interrupt();
- if (latch != null)
- {
- try
- {
- latch.await();
- }
- catch(InterruptedException e)
- {
- Thread.currentThread().interrupt();
- }
- }
- }
- finally
- {
- controller.lockWrite();
- }
- }
- }
- }
-
- // Context queries & registry
-
- public Set<ControllerContext> filter(Iterable<ControllerContext> contexts, ContextFilter filter)
- {
- return registry.filter(contexts, filter);
- }
-
- public Set<ControllerContext> getInstantiatedContexts(Class<?> clazz)
- {
- return registry.getInstantiatedContexts(clazz);
- }
-
- public Set<ControllerContext> getContexts(Class<?> clazz, ControllerState state)
- {
- return registry.getContexts(clazz, state);
- }
-
- public ControllerContext getContextByClass(Class<?> clazz)
- {
- return registry.getContextByClass(clazz);
- }
-
- public void addInstantiatedContext(ControllerContext context)
- {
- registry.addInstantiatedContext(context);
- }
-
- public void registerInstantiatedContext(ControllerContext context, Class<?>... classes)
- {
- registry.registerInstantiatedContext(context, classes);
- }
-
- public void unregisterInstantiatedContext(ControllerContext context, Class<?>... classes)
- {
- registry.unregisterInstantiatedContext(context, classes);
- }
-
- public void removeInstantiatedContext(ControllerContext context)
- {
- registry.removeInstantiatedContext(context);
- }
-
- public Set<Class<?>> getExposedClasses(ControllerContext context)
- {
- return registry.getExposedClasses(context);
- }
-}
Copied: projects/kernel/branches/resolver/dependency/src/main/java/org/jboss/dependency/plugins/AbstractController.java (from rev 99452, projects/kernel/trunk/dependency/src/main/java/org/jboss/dependency/plugins/AbstractController.java)
===================================================================
--- projects/kernel/branches/resolver/dependency/src/main/java/org/jboss/dependency/plugins/AbstractController.java (rev 0)
+++ projects/kernel/branches/resolver/dependency/src/main/java/org/jboss/dependency/plugins/AbstractController.java 2010-01-15 12:19:28 UTC (rev 99462)
@@ -0,0 +1,2596 @@
+/*
+* JBoss, Home of Professional Open Source
+* Copyright 2005, JBoss Inc., and individual contributors as indicated
+* by the @authors tag. See the copyright.txt in the distribution for a
+* full listing of individual contributors.
+*
+* This is free software; you can redistribute it and/or modify it
+* under the terms of the GNU Lesser General Public License as
+* published by the Free Software Foundation; either version 2.1 of
+* the License, or (at your option) any later version.
+*
+* This software is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+* Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public
+* License along with this software; if not, write to the Free
+* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+*/
+package org.jboss.dependency.plugins;
+
+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;
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.CopyOnWriteArraySet;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.Executor;
+import java.util.concurrent.RejectedExecutionException;
+import java.util.concurrent.locks.ReentrantReadWriteLock;
+
+import org.jboss.dependency.plugins.action.ControllerContextAction;
+import org.jboss.dependency.plugins.action.SimpleControllerContextAction;
+import org.jboss.dependency.plugins.tracker.AbstractContextRegistry;
+import org.jboss.dependency.spi.CallbackItem;
+import org.jboss.dependency.spi.Controller;
+import org.jboss.dependency.spi.ControllerContext;
+import org.jboss.dependency.spi.ControllerContextActions;
+import org.jboss.dependency.spi.ControllerMode;
+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.dependency.spi.asynchronous.AsynchronousController;
+import org.jboss.dependency.spi.graph.GraphController;
+import org.jboss.dependency.spi.graph.LookupStrategy;
+import org.jboss.dependency.spi.graph.SearchInfo;
+import org.jboss.dependency.spi.tracker.ContextFilter;
+import org.jboss.dependency.spi.tracker.ContextQueries;
+import org.jboss.dependency.spi.tracker.ContextRegistry;
+import org.jboss.util.JBossObject;
+import org.jboss.util.collection.CollectionsFactory;
+
+/**
+ * Abstract controller.
+ *
+ * @author <a href="adrian at jboss.com">Adrian Brock</a>
+ * @author <a href="ales.justin at jboss.com">Ales Justin</a>
+ * @author <a href="kabir.khan at jboss.com">Kabir Khan</a>
+ * @version $Revision$
+ */
+public class AbstractController extends JBossObject implements Controller, GraphController, AbstractControllerMBean, AsynchronousController, ContextQueries, ContextRegistry
+{
+ /** The lock */
+ private ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
+
+ /**
+ * The executor used to install ASYNCHRONOUS contexts. It must have a saturation policy of
+ * (or semantically similar to) ThreadPoolExecutor.AbortPolicy or ThreadPoolExecutor.CallerRunsPolicy
+ */
+ private Executor executor;
+
+ /** Whether we are shutdown */
+ private boolean shutdown = false;
+
+ /** The controller state model */
+ private final AbstractControllerStateModel stateModel = new MapControllerStateModel();
+
+ /** All contexts by name Map<Object, ControllerContext> */
+ private final Map<Object, ControllerContext> allContexts = new ConcurrentHashMap<Object, ControllerContext>();
+
+ /** The contexts by state Map<ControllerState, Set<ControllerContext>> */
+ private final Map<ControllerState, Set<ControllerContext>> contextsByState = new ConcurrentHashMap<ControllerState, Set<ControllerContext>>();
+
+ /** The error contexts Map<Name, ControllerContext> */
+ private final Map<Object, ControllerContext> errorContexts = new ConcurrentHashMap<Object, ControllerContext>();
+
+ /** The contexts that are currently being resolved/installed */
+ private final Set<ControllerContext> installing = new CopyOnWriteArraySet<ControllerContext>();
+
+ /** The contexts that are currently being installed by the executor */
+ private final ContextsInstalledByExecutor contextsInstalledByExecutor = new ContextsInstalledByExecutor();
+
+ /** The parent controller */
+ private volatile AbstractController parentController;
+
+ /** The child controllers */
+ private final Set<AbstractController> childControllers = new CopyOnWriteArraySet<AbstractController>();
+
+ /** The callback items */
+ private final Map<Object, Set<CallbackItem<?>>> installCallbacks = new ConcurrentHashMap<Object, Set<CallbackItem<?>>>();
+ private final Map<Object, Set<CallbackItem<?>>> uninstallCallbacks = new ConcurrentHashMap<Object, Set<CallbackItem<?>>>();
+
+ /** Whether an on demand context has been enabled */
+ private boolean onDemandEnabled = true;
+
+ /** Whether stats are enabled */
+ private boolean collectStats = false;
+
+ /** The install stats */
+ private volatile StateStatistics installStats = null;
+
+ /** The context tracker */
+ private final AbstractContextRegistry registry;
+
+ /**
+ * Create an abstract controller
+ */
+ public AbstractController()
+ {
+ addState(ControllerState.NOT_INSTALLED, null);
+ addState(ControllerState.PRE_INSTALL, null);
+ addState(ControllerState.DESCRIBED, null);
+ addState(ControllerState.INSTANTIATED, null);
+ addState(ControllerState.CONFIGURED, null);
+ addState(ControllerState.CREATE, null);
+ addState(ControllerState.START, null);
+ addState(ControllerState.INSTALLED, null);
+
+ registry = createContextRegistry();
+ }
+
+ /**
+ * Create context registry.
+ *
+ * @return the context registry
+ */
+ protected AbstractContextRegistry createContextRegistry()
+ {
+ return new AbstractContextRegistry(this);
+ }
+
+ /**
+ * Set the executor used to install ASYNCHRONOUS contexts. It must have a saturation policy of
+ * (or semantically similar to) ThreadPoolExecutor.AbortPolicy or ThreadPoolExecutor.CallerRunsPolicy.
+ *
+ * @param executor the executor
+ */
+ public void setExecutor(Executor executor)
+ {
+ // TODO - security
+ lockWrite();
+ try
+ {
+ this.executor = executor;
+ }
+ finally
+ {
+ unlockWrite();
+ }
+ }
+
+ /**
+ * Get the executor.
+ *
+ * @return the executor
+ */
+ public Executor getExecutor()
+ {
+ // TODO - security
+ return getExecutionEnvironment();
+ }
+
+ /**
+ * Get the executor internal w/o security check.
+ *
+ * @return the executor
+ */
+ protected Executor getExecutionEnvironment()
+ {
+ lockRead();
+ try
+ {
+ return executor;
+ }
+ finally
+ {
+ unlockRead();
+ }
+ }
+
+ public boolean isShutdown()
+ {
+ lockWrite();
+ try
+ {
+ return shutdown;
+ }
+ finally
+ {
+ unlockWrite();
+ }
+ }
+
+ /**
+ * Check whether the controller is shutdown
+ *
+ * @throws IllegalStateException when already shutdown
+ */
+ public void checkShutdown()
+ {
+ lockWrite();
+ try
+ {
+ if (shutdown)
+ throw new IllegalStateException("Already shutdown");
+ }
+ finally
+ {
+ unlockWrite();
+ }
+ }
+
+ public void shutdown()
+ {
+ lockWrite();
+ try
+ {
+ Set<AbstractController> children = getControllers();
+ if (children != null && children.isEmpty() == false)
+ {
+ for (AbstractController child : children)
+ {
+ try
+ {
+ child.shutdown();
+ }
+ catch (Throwable t)
+ {
+ log.warn("Error during shutdown of child: " + child, t);
+ }
+ }
+ }
+
+ Set<ControllerContext> contexts = getAllContexts();
+ if (contexts != null && contexts.isEmpty() == false)
+ {
+ for (ControllerContext context : contexts)
+ {
+ try
+ {
+ uninstall(context.getName());
+ }
+ catch (Throwable t)
+ {
+ log.warn("Error during shutdown while uninstalling: " + context, t);
+ }
+ }
+ }
+ }
+ finally
+ {
+ shutdown = true;
+ unlockWrite();
+ }
+
+ }
+
+ /**
+ * Get the collectStats.
+ *
+ * @return the collectStats.
+ */
+ public boolean isCollectStats()
+ {
+ return collectStats;
+ }
+
+ /**
+ * Set the collectStats.
+ *
+ * @param collectStats the collectStats.
+ */
+ public void setCollectStats(boolean collectStats)
+ {
+ this.collectStats = collectStats;
+ }
+
+ public String listStateTimes(boolean details)
+ {
+ synchronized (this)
+ {
+ if (installStats == null)
+ return "No statistics available";
+ return installStats.listTimes(details);
+ }
+ }
+
+ public void addState(ControllerState state, ControllerState before)
+ {
+ lockWrite();
+ try
+ {
+ if (stateModel.addState(state, before))
+ {
+ Set<ControllerContext> contexts = new CopyOnWriteArraySet<ControllerContext>();
+ contextsByState.put(state, contexts);
+ }
+ }
+ finally
+ {
+ unlockWrite();
+ }
+ }
+
+ /**
+ * Add controller context.
+ *
+ * This is normally used when switching from top
+ * level controller to a scoped one.
+ *
+ * @param context the controller context
+ */
+ void addControllerContext(ControllerContext context)
+ {
+ lockWrite();
+ try
+ {
+ registerControllerContext(context);
+ }
+ finally
+ {
+ unlockWrite();
+ }
+ }
+
+ /**
+ * Remove controller context.
+ *
+ * This is normally used when switching from scoped
+ * level controller to a top one.
+ *
+ * @param context the controller context
+ */
+ void removeControllerContext(ControllerContext context)
+ {
+ lockWrite();
+ try
+ {
+ unregisterControllerContext(context);
+ }
+ finally
+ {
+ unlockWrite();
+ }
+ }
+
+ /**
+ * Get the parent controller.
+ *
+ * @return the parent controller
+ */
+ public AbstractController getParentController()
+ {
+ return parentController;
+ }
+
+ /**
+ * Set the parent controller.
+ *
+ * @param parentController the parent controller
+ */
+ protected void setParentController(AbstractController parentController)
+ {
+ this.parentController = parentController;
+ }
+
+ /**
+ * Get child controllers.
+ *
+ * @return the child controllers
+ */
+ public Set<AbstractController> getControllers()
+ {
+ lockRead();
+ try
+ {
+ return Collections.unmodifiableSet(childControllers);
+ }
+ finally
+ {
+ unlockRead();
+ }
+ }
+
+ /**
+ * Add child controller.
+ *
+ * @param controller the child controller
+ * @return true if equal controller has been already added, see Set.add usage
+ */
+ public boolean addController(AbstractController controller)
+ {
+ lockWrite();
+ try
+ {
+ return childControllers.add(controller);
+ }
+ finally
+ {
+ unlockWrite();
+ }
+ }
+
+ /**
+ * Remove child controller.
+ *
+ * @param controller the child controller
+ * @return true if equal controller was present, see Set.remove usage
+ */
+ public boolean removeController(AbstractController controller)
+ {
+ lockWrite();
+ try
+ {
+ return childControllers.remove(controller);
+ }
+ finally
+ {
+ unlockWrite();
+ }
+ }
+
+ /**
+ * Whether the controller has contexts
+ *
+ * @return true when there are registered contexts
+ */
+ public boolean isActive()
+ {
+ lockRead();
+ try
+ {
+ // is this active
+ if (allContexts.isEmpty() == false)
+ return true;
+
+ // any of the children still active
+ for (AbstractController child : getControllers())
+ {
+ if (child.isActive())
+ return true;
+ }
+
+ return false;
+ }
+ finally
+ {
+ unlockRead();
+ }
+ }
+
+ public ControllerContext getContext(Object name, ControllerState state, SearchInfo info)
+ {
+ if (info == null)
+ throw new IllegalArgumentException("Null search info.");
+
+ LookupStrategy strategy = info.getStrategy();
+ if (strategy == null)
+ throw new IllegalArgumentException("AbstractController doesn't implement this search info: " + info);
+
+ if (log.isTraceEnabled())
+ log.trace("Executing search " + info.getType());
+
+ return strategy.getContext(this, name, state);
+ }
+
+ /**
+ * Get all the contexts.
+ * In state decending order.
+ *
+ * @return all contexts
+ */
+ public Set<ControllerContext> getAllContexts()
+ {
+ lockRead();
+ try
+ {
+ LinkedHashSet<ControllerContext> result = new LinkedHashSet<ControllerContext>();
+ ListIterator<ControllerState> it = stateModel.listIteraror();
+ if (it.hasNext())
+ {
+ result.addAll(getContextsByState(it.next()));
+ while (it.hasPrevious())
+ {
+ result.addAll(getContextsByState(it.previous()));
+ }
+ }
+ result.addAll(errorContexts.values());
+ return result;
+ }
+ finally
+ {
+ unlockRead();
+ }
+ }
+
+ public ControllerContext getContext(Object name, ControllerState state)
+ {
+ if (name == null)
+ throw new IllegalArgumentException("Null name");
+
+ lockRead();
+ try
+ {
+ ControllerContext result = getRegisteredControllerContext(name, false);
+ if (result == null && name instanceof Class) // check type matching
+ result = getContextByClass((Class<?>)name);
+
+ if (result != null && state != null && stateModel.isBeforeState(result.getState(), state))
+ {
+ return null;
+ }
+ return result;
+ }
+ finally
+ {
+ unlockRead();
+ }
+ }
+
+ public ControllerContext getInstalledContext(Object name)
+ {
+ return getContext(name, ControllerState.INSTALLED);
+ }
+
+ public Set<ControllerContext> getNotInstalled()
+ {
+ lockWrite();
+ try
+ {
+ Set<ControllerContext> result = new HashSet<ControllerContext>(errorContexts.values());
+ for (ControllerState state : stateModel)
+ {
+ if (ControllerState.INSTALLED.equals(state))
+ break;
+
+ Set<ControllerContext> stateContexts = getContextsByState(state);
+ result.addAll(stateContexts);
+ }
+ return result;
+ }
+ finally
+ {
+ unlockWrite();
+ }
+ }
+
+ public ControllerStateModel getStates()
+ {
+ return stateModel;
+ }
+
+ public Set<ControllerContext> getContextsByState(ControllerState state)
+ {
+ return contextsByState.get(state);
+ }
+
+ public void install(ControllerContext context) throws Throwable
+ {
+ boolean trace = log.isTraceEnabled();
+
+ if (context == null)
+ throw new IllegalArgumentException("Null context");
+
+ Object name = context.getName();
+ if (name == null)
+ throw new IllegalArgumentException("Null name " + context.toShortString());
+
+ install(context, trace);
+ }
+
+ public void change(ControllerContext context, ControllerState state) throws Throwable
+ {
+ boolean trace = log.isTraceEnabled();
+
+ if (context == null)
+ throw new IllegalArgumentException("Null context");
+
+ if (state == null)
+ throw new IllegalArgumentException("Null state");
+
+ change(context, state, trace);
+ }
+
+ public void enableOnDemand(ControllerContext context) throws Throwable
+ {
+ boolean trace = log.isTraceEnabled();
+
+ if (context == null)
+ throw new IllegalArgumentException("Null context");
+
+ enableOnDemand(context, trace);
+ }
+
+ public ControllerContext uninstall(Object name)
+ {
+ return uninstall(name, 0);
+ }
+
+ /**
+ * Get controller id - impl detail.
+ * It should be unique.
+ *
+ * @return controller's id
+ */
+ protected String getId()
+ {
+ StringBuffer buffer = new StringBuffer();
+ buffer.append(getClass().getSimpleName());
+ buffer.append("[").append(System.identityHashCode(this)).append("]");
+ return buffer.toString();
+ }
+
+ public void addAlias(Object alias, Object original) throws Throwable
+ {
+ Map<ControllerState, ControllerContextAction> map = createAliasActions();
+ ControllerContextActions actions = new AbstractControllerContextActions(map);
+ AliasControllerContext context = new InnerAliasControllerContext(alias, getId(), original, actions);
+ preAliasInstall(context);
+ install(context);
+ // is alias in error
+ Throwable error = context.getError();
+ if (error != null)
+ throw error;
+ if (ControllerState.ERROR.equals(context.getState()))
+ throw new IllegalArgumentException("Alias " + context + " is in error.");
+ }
+
+ /**
+ * Create alias controller context actions.
+ *
+ * @return the alias controller context actions
+ */
+ protected Map<ControllerState, ControllerContextAction> createAliasActions()
+ {
+ return Collections.<ControllerState, ControllerContextAction>singletonMap(ControllerState.INSTALLED, new AliasControllerContextAction());
+ }
+
+ /**
+ * Apply pre install - e.g. scope key in scoped controller.
+ *
+ * @param aliasContext the new alias context
+ */
+ protected void preAliasInstall(ControllerContext aliasContext)
+ {
+ }
+
+ public void removeAlias(Object alias)
+ {
+ uninstall(alias + "_Alias_" + getId());
+ }
+
+ /**
+ * Uninstall the context.
+ *
+ * @param name the context name
+ * @param level the controller level
+ * @return uninstalled controller context
+ */
+ // todo - some better way to find context's by name
+ // currently the first one found is used
+ protected ControllerContext uninstall(Object name, int level)
+ {
+ boolean trace = log.isTraceEnabled();
+
+ if (name == null)
+ throw new IllegalArgumentException("Null name");
+
+ lockWrite();
+ try
+ {
+ if (errorContexts.remove(name) != null && trace)
+ log.trace("Tidied up context in error state: " + name);
+
+ ControllerContext context = getRegisteredContextAndInterruptAsynchronousInstall(name);
+ if (context != null)
+ {
+ if (trace)
+ log.trace("Uninstalling " + context.toShortString());
+
+ // get a hold on possible parent before its nullified in uninstall
+ AbstractController parent = getParentController();
+
+ uninstallContext(context, stateModel.getInitialState(), trace);
+
+ try
+ {
+ unregisterControllerContext(context);
+ }
+ catch (Throwable t)
+ {
+ log.warn("Error unregistering context: " + context.toShortString() + " with name: " + name);
+ }
+
+ while (parent != null)
+ {
+ try
+ {
+ parent.unregisterControllerContext(context);
+ }
+ catch (Throwable t)
+ {
+ log.warn("Error unregistering context in parent controller: " + context.toShortString() + " with name: " + name);
+ }
+ parent = parent.getParentController();
+ }
+ }
+ else
+ {
+ for (AbstractController controller : getControllers())
+ {
+ context = controller.uninstall(name, level + 1);
+ if (context != null)
+ break;
+ }
+ }
+ if (context == null && level == 0)
+ throw new IllegalStateException("Not installed: " + name);
+ return context;
+ }
+ finally
+ {
+ unlockWrite();
+ }
+ }
+
+
+ /**
+ * Obtains the context, having interrupted its installation process if it is an asynchronous context
+ * currently being installed
+ * @param name The name of the context
+ * @return the context or null if not found
+ */
+ private ControllerContext getRegisteredContextAndInterruptAsynchronousInstall(Object name)
+ {
+ ControllerContext context = getRegisteredControllerContext(name, false);
+ if (context != null)
+ {
+ contextsInstalledByExecutor.interruptTaskAndBlock(context, this);
+ context = getRegisteredControllerContext(name, false);
+ }
+ return context;
+ }
+
+ /**
+ * Install a context
+ *
+ * @param context the context
+ * @param trace whether trace is enabled
+ * @throws Throwable for any error
+ */
+ protected void install(ControllerContext context, boolean trace) throws Throwable
+ {
+ lockWrite();
+ try
+ {
+ checkShutdown();
+
+ Object name = context.getName();
+
+ // Check the name is not already registered
+ if (getRegisteredControllerContext(name, false) != null)
+ throw new IllegalStateException(name + " is already installed.");
+
+ // Check any alias is not already registered
+ Set<Object> aliases = context.getAliases();
+ if (aliases != null && aliases.isEmpty() == false)
+ {
+ for (Object alias : aliases)
+ {
+ if (getRegisteredControllerContext(alias, false) != null)
+ throw new IllegalStateException(alias + " an alias of " + name + " is already installed.");
+ }
+ }
+
+ // set the required state
+ ControllerMode mode = context.getMode();
+ context.setRequiredState(mode.getRequiredState());
+
+ if (trace)
+ log.trace("Installing " + context.toShortString());
+
+ context.setController(this);
+ DependencyInfo dependencies = context.getDependencyInfo();
+ if (trace)
+ {
+ String dependsOn = "[]";
+ if (dependencies != null)
+ {
+ try
+ {
+ Set<DependencyItem> set = dependencies.getIDependOn(null);
+ if (set != null)
+ dependsOn = set.toString();
+ }
+ catch (Throwable t)
+ {
+ log.warn("Exception getting dependencies: " + t);
+ dependsOn = null;
+ }
+ }
+ if (dependsOn != null)
+ log.trace("Dependencies for " + name + ": " + dependsOn);
+ }
+
+ boolean ok = incrementState(context, trace);
+ if (ok)
+ {
+ try
+ {
+ registerControllerContext(context);
+ }
+ catch (Throwable t)
+ {
+ // This is probably unreachable? But let's be paranoid
+ ok = false;
+ throw t;
+ }
+ }
+ if (ok)
+ {
+ resolveContexts(trace);
+ }
+ else
+ {
+ errorContexts.remove(context);
+ throw context.getError();
+ }
+ }
+ finally
+ {
+ unlockWrite();
+ }
+ }
+
+ /**
+ * Change a context's state
+ *
+ * @param context the context
+ * @param state the required state
+ * @param trace whether trace is enabled
+ * @throws Throwable for any error
+ */
+ protected void change(ControllerContext context, ControllerState state, boolean trace) throws Throwable
+ {
+ lockWrite();
+ try
+ {
+ checkShutdown();
+
+ if (!stateModel.isValidState(state))
+ throw new IllegalArgumentException("Unknown state: " + state);
+
+ if (context.getState().equals(state))
+ {
+ if (trace)
+ log.trace("No change required toState=" + state.getStateString() + " " + context.toShortString());
+ return;
+ }
+
+ if (trace)
+ log.trace("Change toState=" + state.getStateString() + " " + context.toShortString());
+
+ context.setRequiredState(state);
+
+ if (stateModel.isBeforeState(context.getState(), state))
+ resolveContexts(trace);
+ else
+ {
+ while (stateModel.isAfterState(context.getState(), state))
+ {
+ uninstallContext(context, trace);
+ }
+ }
+ }
+ finally
+ {
+ unlockWrite();
+ }
+ }
+
+ /**
+ * Enable an on demand context
+ *
+ * @param context the context
+ * @param trace whether trace is enabled
+ * @throws Throwable for any error
+ */
+ protected void enableOnDemand(ControllerContext context, boolean trace) throws Throwable
+ {
+ Controller controller = null;
+ lockWrite();
+ try
+ {
+ checkShutdown();
+
+ controller = context.getController();
+
+ // Already done
+ if (ControllerState.INSTALLED.equals(context.getRequiredState()))
+ return;
+
+ if (controller == this)
+ {
+ if (ControllerMode.ON_DEMAND.equals(context.getMode()) == false)
+ throw new IllegalStateException("Context is not ON DEMAND: " + context.toShortString());
+
+ // Sanity check
+ getRegisteredControllerContext(context.getName(), true);
+
+ context.setRequiredState(ControllerState.INSTALLED);
+
+ if (trace)
+ log.trace("Enable onDemand: " + context.toShortString());
+ }
+ }
+ finally
+ {
+ unlockWrite();
+ }
+
+ if (controller != this)
+ {
+ controller.enableOnDemand(context);
+ }
+
+ lockWrite();
+ try
+ {
+ onDemandEnabled = true;
+ }
+ finally
+ {
+ unlockWrite();
+ }
+ }
+
+ /**
+ * Increment state<p>
+ * <p/>
+ * This method must be invoked with the write lock taken.
+ *
+ * @param context the context
+ * @param trace whether trace is enabled
+ * @return whether the suceeded
+ */
+ protected boolean incrementState(ControllerContext context, boolean trace)
+ {
+ ControllerState fromState = context.getState();
+
+ Controller fromController = context.getController();
+ Set<ControllerContext> fromContexts;
+
+ ControllerState toState;
+ if (ControllerState.ERROR.equals(fromState))
+ {
+ ControllerState initialState = stateModel.getInitialState();
+ errorContexts.remove(context);
+ Throwable error = null;
+ unlockWrite();
+ try
+ {
+ install(context, ControllerState.ERROR, initialState);
+ }
+ catch (Throwable t)
+ {
+ error = t;
+ }
+ finally
+ {
+ lockWrite();
+ if (error != null)
+ {
+ log.error("Error during initial installation: " + context.toShortString(), error);
+ context.setError(error);
+ errorContexts.put(context.getName(), context);
+ return false;
+ }
+ }
+ Set<ControllerContext> notInstalled = fromController.getContextsByState(initialState);
+ notInstalled.add(context);
+ context.setState(initialState);
+ return true;
+ }
+ else
+ {
+ fromContexts = fromController.getContextsByState(fromState);
+ if (fromContexts.contains(context) == false)
+ throw new IllegalStateException("Context not found in previous state (" + fromState + "): " + context.toShortString());
+ toState = stateModel.getNextState(fromState);
+ if (toState == null)
+ throw new IllegalStateException("No state after " + fromState);
+ }
+
+ unlockWrite();
+ Throwable error = null;
+ try
+ {
+ install(context, fromState, toState);
+
+ if (fromContexts != null)
+ fromContexts.remove(context);
+ Controller toController = context.getController();
+ Set<ControllerContext> toContexts = toController.getContextsByState(toState);
+ toContexts.add(context);
+ context.setState(toState);
+
+ handleInstallLifecycleCallbacks(context, toState);
+ resolveCallbacks(context, toState, true);
+ }
+ catch (Throwable t)
+ {
+ error = t;
+ }
+ finally
+ {
+ lockWrite();
+ if (error != null)
+ {
+ log.error("Error installing to " + toState.getStateString() + ": " + context.toShortString(), error);
+ uninstallContext(context, stateModel.getInitialState(), trace);
+ errorContexts.put(context.getName(), context);
+ context.setError(error);
+ return false;
+ }
+ }
+
+ return true;
+ }
+
+ /**
+ * Resolve unresolved contexts<p>
+ * <p/>
+ * This method must be invoked with the write lock taken
+ *
+ * @param trace whether trace is enabled
+ */
+ 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);
+ }
+ }
+ }
+ }
+
+ /**
+ * 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>
+ * <p/>
+ * This method must be invoked with the write lock taken.
+ *
+ * @param context the context
+ * @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)
+ {
+ boolean asynch = contextsInstalledByExecutor.shouldInstallAsynchronously(context);
+
+ if (asynch)
+ {
+ if (executor == null)
+ {
+ Object ctx = trace ? context : context.getName();
+ log.warn("No executor in controller " + this + " to use installing asynchronous context " + ctx);
+
+ }
+
+ Executor foundExecutor = searchForExecutor();
+ if (foundExecutor != null)
+ {
+ InstallControllerContextTask task = new InstallControllerContextTask(context, trace);
+ contextsInstalledByExecutor.markForTaskExecution(context, task);
+
+ if (trace)
+ log.trace("Recorded for asynchronous installation " + context.getName());
+
+ try
+ {
+ foundExecutor.execute(task);
+ return false;
+ }
+ catch(RejectedExecutionException e)
+ {
+ Object ctx = trace ? context : context.getName();
+ log.warn("Asynchronous execution rejected by executor for context " + ctx + ":" + e.getMessage());
+ contextsInstalledByExecutor.disassociateWithTask(context);
+ }
+ }
+ }
+
+ return incrementState(context, trace);
+ }
+
+ /**
+ * Return the executor stored in this controller or in its parent hierarchy. The nearest executor is returned.
+ * <p/>
+ * This method must be called with the write or read lock taken
+ * @return The found executor
+ */
+ protected Executor searchForExecutor()
+ {
+ if (executor != null)
+ {
+ return executor;
+ }
+ AbstractController parent = getParentController();
+ if (parent != null)
+ {
+ try
+ {
+ parent.lockRead();
+ return parent.searchForExecutor();
+ }
+ finally
+ {
+ parent.unlockRead();
+ }
+ }
+ return null;
+ }
+
+ /**
+ * 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
+ *
+ * @param context the context to uninstall
+ * @param toState the target state
+ * @param trace whether trace is enabled
+ */
+ protected void uninstallContext(ControllerContext context, ControllerState toState, boolean trace)
+ {
+ if (!stateModel.isValidState(toState))
+ log.error("INTERNAL ERROR: unknown state " + toState + " states=" + stateModel, new Exception("STACKTRACE"));
+
+ 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);
+ }
+ }
+
+ /**
+ * Uninstall a context<p>
+ * <p/>
+ * This method must be invoked with the write lock taken
+ *
+ * @param context the context to uninstall
+ * @param trace whether trace is enabled
+ */
+ protected void uninstallContext(ControllerContext context, boolean trace)
+ {
+ Object name = context.getName();
+
+ ControllerState fromState = context.getState();
+
+ if (trace)
+ log.trace("Uninstalling " + name + " from " + fromState.getStateString());
+
+ Controller fromController = context.getController();
+
+ Set<ControllerContext> fromContexts = fromController.getContextsByState(fromState);
+ if (fromContexts == null || fromContexts.remove(context) == false)
+ throw new Error("INTERNAL ERROR: context not found in previous state " + fromState.getStateString() + " context=" + context.toShortString(), new Exception("STACKTRACE"));
+
+ DependencyInfo dependencies = context.getDependencyInfo();
+ if (dependencies != null)
+ {
+ try
+ {
+ Set<DependencyItem> dependsOnMe = dependencies.getDependsOnMe(null);
+ if (dependsOnMe.isEmpty() == false)
+ {
+ for (DependencyItem item : dependsOnMe)
+ {
+ if (item.isResolved())
+ {
+ ControllerState dependentState = item.getDependentState();
+ if (dependentState == null || dependentState.equals(fromState))
+ {
+ if (item.unresolved(this))
+ {
+ Set<ControllerContext> dependents = CollectionsFactory.createLazySet();
+ getContexts(item.getName(), dependents);
+ if (dependents.isEmpty() == false)
+ {
+ ControllerState whenRequired = item.getWhenRequired();
+ if (whenRequired == null)
+ whenRequired = stateModel.getInitialState();
+
+ for (ControllerContext dependent : dependents)
+ {
+ boolean selfDependency = (dependent == context);
+ if (!selfDependency)
+ {
+ contextsInstalledByExecutor.interruptTaskAndBlock(dependent, this);
+ if (stateModel.isBeforeState(dependent.getState(), whenRequired) == false)
+ {
+ uninstallContext(dependent, whenRequired, trace);
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ catch (Throwable error)
+ {
+ log.error("Error resolving 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);
+ }
+ }
+
+ // The state could have changed while calling out to dependents
+ fromState = context.getState();
+ if (ControllerState.ERROR.equals(fromState))
+ return;
+
+ ControllerState toState = stateModel.getPreviousState(fromState);
+ if (toState == null)
+ {
+ // This is hack, we signal true uninstalled status by putting it in the error state
+ context.setState(ControllerState.ERROR);
+ return;
+ }
+
+ unlockWrite();
+ try
+ {
+ resolveCallbacks(context, fromState, false);
+ handleUninstallLifecycleCallbacks(context, toState);
+
+ uninstall(context, fromState, toState);
+
+ Controller toController = context.getController();
+ Set<ControllerContext> toContexts = toController.getContextsByState(toState);
+ toContexts.add(context);
+ context.setState(toState);
+
+ uninstallUnusedOnDemandContexts(context, trace);
+ }
+ catch (Throwable t)
+ {
+ log.warn("Error uninstalling from " + fromState.getStateString() + ": " + context.toShortString(), t);
+ }
+ finally
+ {
+ lockWrite();
+ }
+ }
+
+ /**
+ * If the context being uninstalled depends on On_Demand contexts that are not used anymore
+ * those On_Demand contexts are uninstalled back to the DESCRIBED state.<p>
+ *
+ * This method must be called with NO locks taken.
+ *
+ * @param context the context which is being uninstalled.
+ * @param trace do trace log
+ */
+ protected void uninstallUnusedOnDemandContexts(ControllerContext context, boolean trace)
+ {
+ lockWrite();
+ try
+ {
+ DependencyInfo dependencies = context.getDependencyInfo();
+ if (dependencies != null)
+ {
+ Set<DependencyItem> iDependOn = dependencies.getIDependOn(null);
+ if (iDependOn.isEmpty() == false)
+ {
+ for (DependencyItem item : iDependOn)
+ {
+ if (item.isResolved()) //TODO Is this check necessary
+ {
+ Object name = item.getIDependOn();
+ if (name == null)
+ continue;
+
+ ControllerContext other = getContext(name, null);
+ if (other == null)
+ {
+ log.warn("Could not find dependency '" + name + "' while uninstalling on demand contexts for " + item);
+ continue;
+ }
+ if (other.getMode() != ControllerMode.ON_DEMAND)
+ continue;
+
+ DependencyInfo otherDependencies = other.getDependencyInfo();
+ if (otherDependencies == null)
+ continue;
+
+ Set<DependencyItem> dependsOnOther = otherDependencies.getDependsOnMe(null);
+ boolean isRequired = false;
+ for (DependencyItem dependsOnOtherItem : dependsOnOther)
+ {
+ ControllerContext dependsContext = getContext(dependsOnOtherItem.getName(), null);
+ if (dependsContext == null)
+ {
+ log.warn("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)
+ {
+ //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);
+ }
+ }
+ }
+ }
+ }
+ }
+ finally
+ {
+ unlockWrite();
+ }
+ }
+
+ /**
+ * Get all contexts by name,
+ * check child controllers as well.
+ *
+ * @param name the name of the context
+ * @param contexts found contexts
+ */
+ protected void getContexts(Object name, Set<ControllerContext> contexts)
+ {
+ ControllerContext context = getContext(name, null);
+ if (context != null)
+ {
+ Set<Object> aliases = context.getAliases();
+ // only pick up unique name
+ // TODO also ignore alises from @Aliases?
+ if (aliases == null || aliases.contains(name) == false)
+ contexts.add(context);
+ }
+
+ Set<AbstractController> children = getControllers();
+ if (children != null && children.isEmpty() == false)
+ {
+ for (AbstractController child : children)
+ {
+ child.getContexts(name, contexts);
+ }
+ }
+ }
+
+ /**
+ * Add callback item under demand name.
+ *
+ * @param <T> the callback item type
+ * @param name demand name
+ * @param isInstallPhase install or uninstall phase
+ * @param callback callback item
+ */
+ protected <T> void addCallback(Object name, boolean isInstallPhase, CallbackItem<T> callback)
+ {
+ lockWrite();
+ try
+ {
+ Map<Object, Set<CallbackItem<?>>> map = (isInstallPhase ? installCallbacks : uninstallCallbacks);
+ Set<CallbackItem<?>> callbacks = map.get(name);
+ if (callbacks == null)
+ {
+ callbacks = new HashSet<CallbackItem<?>>();
+ map.put(name, callbacks);
+ }
+ callbacks.add(callback);
+ }
+ finally
+ {
+ unlockWrite();
+ }
+ }
+
+ /**
+ * Remove callback item under demand name.
+ *
+ * @param <T> the callback item type
+ * @param name demand name
+ * @param isInstallPhase install or uninstall phase
+ * @param callback callback item
+ */
+ protected <T> void removeCallback(Object name, boolean isInstallPhase, CallbackItem<T> callback)
+ {
+ lockWrite();
+ try
+ {
+ Map<Object, Set<CallbackItem<?>>> map = (isInstallPhase ? installCallbacks : uninstallCallbacks);
+ Set<CallbackItem<?>> callbacks = map.get(name);
+ if (callbacks != null)
+ {
+ callbacks.remove(callback);
+ if (callbacks.isEmpty())
+ map.remove(name);
+ }
+ }
+ finally
+ {
+ unlockWrite();
+ }
+ }
+
+ /**
+ * Get calbacks from context.
+ *
+ * @param context current context
+ * @param isInstallPhase install or uninstall phase
+ * @return callback items from dependency info
+ */
+ protected Set<CallbackItem<?>> getDependencyCallbacks(ControllerContext context, boolean isInstallPhase)
+ {
+ DependencyInfo di = context.getDependencyInfo();
+ if (di != null)
+ {
+ return isInstallPhase ? di.getInstallItems() : di.getUninstallItems();
+ }
+ return null;
+ }
+
+ /**
+ * Get the matching callbacks.
+ *
+ * @param name demand name
+ * @param isInstallPhase install or uninstall phase
+ * @return all matching registered callbacks or empty set if no such item
+ */
+ protected Set<CallbackItem<?>> getCallbacks(Object name, boolean isInstallPhase)
+ {
+ lockRead();
+ try
+ {
+ Map<Object, Set<CallbackItem<?>>> map = (isInstallPhase ? installCallbacks : uninstallCallbacks);
+ Set<CallbackItem<?>> callbacks = map.get(name);
+ return callbacks != null ? callbacks : Collections.<CallbackItem<?>>emptySet();
+ }
+ finally
+ {
+ unlockRead();
+ }
+ }
+
+ /**
+ * Resolve callbacks.
+ *
+ * @param callbacks the callbacks
+ * @param state current context state
+ * @param execute do execute callback
+ * @param isInstallPhase install or uninstall phase
+ * @param type install or uninstall type
+ */
+ protected void resolveCallbacks(Set<CallbackItem<?>> callbacks, ControllerState state, boolean execute, boolean isInstallPhase, boolean type)
+ {
+ if (callbacks != null && callbacks.isEmpty() == false)
+ {
+ for (CallbackItem<?> callback : callbacks)
+ {
+ if (callback.getWhenRequired().equals(state))
+ {
+ if (isInstallPhase)
+ {
+ addCallback(callback.getIDependOn(), type, callback);
+ }
+ else
+ {
+ removeCallback(callback.getIDependOn(), type, callback);
+ }
+ if (execute)
+ {
+ try
+ {
+ callback.ownerCallback(this, isInstallPhase);
+ }
+ catch (Throwable t)
+ {
+ log.warn("Broken callback: " + callback, t);
+ }
+ }
+ }
+ }
+ }
+ }
+
+ /**
+ * Resolve callback items.
+ *
+ * @param context current context
+ * @param state current context state
+ * @param isInstallPhase install or uninstall phase
+ */
+ protected void resolveCallbacks(ControllerContext context, ControllerState state, boolean isInstallPhase)
+ {
+ ClassLoader previous = null;
+ try
+ {
+ previous = SecurityActions.setContextClassLoader(context);
+ // existing owner callbacks
+ Set<CallbackItem<?>> installs = getDependencyCallbacks(context, true);
+ resolveCallbacks(installs, state, isInstallPhase, isInstallPhase, true);
+ Set<CallbackItem<?>> uninstalls = getDependencyCallbacks(context, false);
+ resolveCallbacks(uninstalls, state, isInstallPhase == false, isInstallPhase, false);
+
+ // change callbacks, applied only if context is autowire candidate
+ DependencyInfo dependencyInfo = context.getDependencyInfo();
+ if (dependencyInfo != null && dependencyInfo.isAutowireCandidate())
+ {
+ // match callbacks by name
+ Set<CallbackItem<?>> existingCallbacks = new HashSet<CallbackItem<?>>();
+ existingCallbacks.addAll(getCallbacks(context.getName(), isInstallPhase));
+ // match by classes
+ Collection<Class<?>> classes = getExposedClasses(context);
+ if (classes != null && classes.isEmpty() == false)
+ {
+ for (Class<?> clazz : classes)
+ {
+ existingCallbacks.addAll(getCallbacks(clazz, isInstallPhase));
+ }
+ }
+
+ // Do the installs if we are at the required state
+ if (existingCallbacks != null && existingCallbacks.isEmpty() == false)
+ {
+ for(CallbackItem<?> callback : existingCallbacks)
+ {
+ if (state.equals(callback.getDependentState()))
+ {
+ try
+ {
+ callback.changeCallback(this, context, isInstallPhase);
+ }
+ catch (Throwable t)
+ {
+ log.warn("Broken callback: " + callback, t);
+ }
+ }
+ }
+ }
+ }
+ }
+ // let's make sure we suppress any exceptions
+ catch (Throwable t)
+ {
+ log.warn("Cannot resolve callbacks, state= " + state + ", isInstall= " + isInstallPhase + ", context= " + context, t);
+ }
+ finally
+ {
+ if (previous != null)
+ SecurityActions.resetContextClassLoader(previous);
+ }
+ }
+
+ /**
+ * Handle install lifecycle callbacks.
+ *
+ * @param context the context
+ * @param state the state
+ * @throws Throwable for any error
+ */
+ protected void handleInstallLifecycleCallbacks(ControllerContext context, ControllerState state) throws Throwable
+ {
+ handleLifecycleCallbacks(context, state, true);
+ }
+
+ /**
+ * Handle uninstall lifecycle callbacks.
+ *
+ * @param context the context
+ * @param state the state
+ * @throws Throwable for any error
+ */
+ protected void handleUninstallLifecycleCallbacks(ControllerContext context, ControllerState state) throws Throwable
+ {
+ ControllerState oldState = stateModel.getNextState(state);
+ handleLifecycleCallbacks(context, oldState, false);
+ }
+
+ /**
+ * Handle lifecycle callbacks.
+ *
+ * @param context the context
+ * @param state the state
+ * @param install is it install or uninstall
+ * @throws Throwable for any error
+ */
+ protected void handleLifecycleCallbacks(ControllerContext context, ControllerState state, boolean install) throws Throwable
+ {
+ DependencyInfo di = context.getDependencyInfo();
+ if (di != null)
+ {
+ List<LifecycleCallbackItem> callbacks = di.getLifecycleCallbacks();
+ for (LifecycleCallbackItem callback : callbacks)
+ {
+ if (callback.getWhenRequired().equals(state))
+ {
+ if (install)
+ callback.install(context);
+ else
+ callback.uninstall(context);
+ }
+ }
+ }
+ }
+
+ /**
+ * Install a context<p>
+ * <p/>
+ * This method must be invoked with NO locks taken
+ *
+ * @param context the context
+ * @param fromState the from state
+ * @param toState the toState
+ * @throws Throwable for any error
+ */
+ protected void install(ControllerContext context, ControllerState fromState, ControllerState toState) throws Throwable
+ {
+ long time = 0;
+ boolean collectStats = this.collectStats;
+ if (collectStats)
+ time = System.currentTimeMillis();
+ try
+ {
+ context.install(fromState, toState);
+ }
+ finally
+ {
+ if (collectStats)
+ {
+ time = System.currentTimeMillis() - time;
+ if (time > 0)
+ {
+ synchronized (this)
+ {
+ if (installStats == null)
+ installStats = new StateStatistics();
+
+ String state = toState.getStateString();
+ String name = context.getName().toString();
+ installStats.addStatistic(state, name, time);
+ }
+ }
+ }
+ }
+ }
+
+ /**
+ * Uninstall a context<p>
+ * <p/>
+ * This method must be invoked with NO locks taken
+ *
+ * @param context the context
+ * @param fromState the from state
+ * @param toState the to state
+ */
+ protected void uninstall(ControllerContext context, ControllerState fromState, ControllerState toState)
+ {
+ context.uninstall(fromState, toState);
+ }
+
+ /**
+ * Whether we should advance the context<p>
+ * <p/>
+ * This method must be invoked with the write lock taken
+ *
+ * @param context the context
+ * @return true when we should advance the context
+ */
+ protected boolean advance(ControllerContext context)
+ {
+ ControllerMode mode = context.getMode();
+
+ // Never advance for disabled
+ if (ControllerMode.DISABLED.equals(mode))
+ return false;
+
+ return stateModel.isBeforeState(context.getState(), context.getRequiredState());
+ }
+
+ /**
+ * Lock for read
+ */
+ protected void lockRead()
+ {
+ lock.readLock().lock();
+ }
+
+ /**
+ * Unlock for read
+ */
+ protected void unlockRead()
+ {
+ lock.readLock().unlock();
+ }
+
+ /**
+ * Lock for write
+ */
+ protected void lockWrite()
+ {
+ lock.writeLock().lock();
+ }
+
+ /**
+ * Unlock for write
+ */
+ protected void unlockWrite()
+ {
+ lock.writeLock().unlock();
+ }
+
+ /**
+ * Get a registered context<p>
+ * <p/>
+ * This method should be invoked with at least the read lock taken
+ *
+ * @param name the name with which to register it
+ * @param mustExist whether to throw an error when the context does not exist
+ * @return context the registered context
+ * @throws IllegalArgumentException for null parameters
+ * @throws IllegalStateException if the context if must exist is true and the context does not exist
+ */
+ protected ControllerContext getRegisteredControllerContext(Object name, boolean mustExist)
+ {
+ if (name == null)
+ throw new IllegalArgumentException("Null name");
+
+ ControllerContext result = allContexts.get(name);
+ if (mustExist && result == null)
+ throw new IllegalStateException("Context does not exist with name: " + name);
+ return result;
+ }
+
+ /**
+ * Register a context and all its aliases<p>
+ * <p/>
+ * This method must be invoked with the write lock taken
+ *
+ * @param context the context to register
+ * @throws IllegalArgumentException for null parameters
+ * @throws IllegalStateException if the context is already registered with that name or alias
+ */
+ protected void registerControllerContext(ControllerContext context)
+ {
+ if (context == null)
+ throw new IllegalArgumentException("Null context");
+
+ Set<Object> aliases = context.getAliases();
+
+ // Register the context
+ Object name = context.getName();
+ registerControllerContext(name, context);
+
+ // Register the aliases
+ if (aliases != null && aliases.isEmpty() == false)
+ {
+ int ok = 0;
+ try
+ {
+ for (Object alias : aliases)
+ {
+ registerControllerContext(alias, context);
+ ++ok;
+ }
+ }
+ finally
+ {
+ // It didn't work
+ if (ok != aliases.size() && ok > 0)
+ {
+ // Unregister the aliases we added
+ for (Object alias : aliases)
+ {
+ if (ok-- == 0)
+ break;
+ try
+ {
+ unregisterControllerContext(alias);
+ }
+ catch (Throwable ignored)
+ {
+ log.debug("Error unregistering alias: " + alias, ignored);
+ }
+ }
+
+ // Unregister the context
+ try
+ {
+ unregisterControllerContext(name);
+ }
+ catch (Throwable ignored)
+ {
+ log.debug("Error unregistering context with name: " + name, ignored);
+ }
+ }
+ }
+ }
+ }
+
+ /**
+ * Unregister a context and all its aliases<p>
+ * <p/>
+ * This method must be invoked with the write lock taken
+ *
+ * @param context the context
+ * @throws IllegalArgumentException for null parameters
+ * @throws IllegalStateException if the context is not registered
+ */
+ protected void unregisterControllerContext(ControllerContext context)
+ {
+ if (context == null)
+ throw new IllegalArgumentException("Null context");
+
+ Set<Object> aliases = context.getAliases();
+
+ // Unregister the context
+ Object name = context.getName();
+ unregisterControllerContext(name);
+
+ // Unegister the aliases
+ if (aliases != null && aliases.isEmpty() == false)
+ {
+ for (Object alias : aliases)
+ {
+ try
+ {
+ unregisterControllerContext(alias);
+ }
+ catch (Throwable ignored)
+ {
+ log.debug("Error unregistering alias: " + alias, ignored);
+ }
+ }
+ }
+ }
+
+ /**
+ * Register a context<p>
+ * <p/>
+ * This method must be invoked with the write lock taken<p>
+ * <p/>
+ * NOTE: You probably want to use the {@link #registerControllerContext(ControllerContext)}
+ *
+ * @param name the name with which to register it
+ * @param context the context to register
+ * @throws IllegalArgumentException for null parameters
+ * @throws IllegalStateException if the context is already registered with that name
+ */
+ protected void registerControllerContext(Object name, ControllerContext context)
+ {
+ if (name == null)
+ throw new IllegalArgumentException("Null name");
+ if (context == null)
+ throw new IllegalArgumentException("Null context");
+
+ if (allContexts.containsKey(name) == false)
+ allContexts.put(name, context);
+ else
+ throw new IllegalStateException("Unable to register context " + context.toShortString() + ", name already exists: " + name);
+ }
+
+ /**
+ * Unregister a context<p>
+ * <p/>
+ * This method must be invoked with the write lock taken<p>
+ * <p/>
+ * NOTE: You probably want to use the {@link #unregisterControllerContext(ControllerContext)}
+ *
+ * @param name the name it was registered with
+ * @throws IllegalArgumentException for null parameters
+ */
+ protected void unregisterControllerContext(Object name)
+ {
+ if (name == null)
+ throw new IllegalArgumentException("Null name");
+ allContexts.remove(name);
+ }
+
+ // --- alias dependency
+
+ private static class InnerAliasControllerContext extends AbstractAliasControllerContext
+ {
+ private InnerAliasControllerContext(Object alias, String id, Object original, ControllerContextActions actions)
+ {
+ super(alias, id, original, actions);
+ }
+ }
+
+ private class AliasControllerContextAction extends SimpleControllerContextAction<AliasControllerContext>
+ {
+ protected AliasControllerContext contextCast(ControllerContext context)
+ {
+ return AliasControllerContext.class.cast(context);
+ }
+
+ protected boolean validateContext(ControllerContext context)
+ {
+ return (context instanceof AliasControllerContext);
+ }
+
+ protected void installAction(AliasControllerContext context) throws Throwable
+ {
+ Object alias = context.getAlias();
+ Object jmxAlias = JMXObjectNameFix.needsAnAlias(alias);
+ if (jmxAlias != null)
+ alias = jmxAlias;
+
+ Object original = context.getOriginal();
+ Object jmxOriginal = JMXObjectNameFix.needsAnAlias(original);
+ if (jmxOriginal != null)
+ original = jmxOriginal;
+
+ // get the context's controller - not the one we registered with
+ AbstractController controller = (AbstractController)context.getController();
+ lockWrite();
+ try
+ {
+ ControllerContext lookup = controller.getRegisteredControllerContext(original, true);
+ controller.registerControllerContext(alias, lookup);
+ if (log.isTraceEnabled())
+ log.trace("Added alias " + alias + " for context " + context);
+ }
+ finally
+ {
+ unlockWrite();
+ }
+ }
+
+ protected void uninstallAction(AliasControllerContext context)
+ {
+ lockWrite();
+ try
+ {
+ Object alias = context.getAlias();
+ Object jmxAlias = JMXObjectNameFix.needsAnAlias(alias);
+ if (jmxAlias != null)
+ alias = jmxAlias;
+
+ // get the context's controller - not the one we registered with
+ AbstractController controller = (AbstractController)context.getController();
+ controller.unregisterControllerContext(alias);
+ if (log.isTraceEnabled())
+ log.trace("Removed alias " + alias);
+ }
+ finally
+ {
+ unlockWrite();
+ }
+ }
+ }
+
+ public boolean isAsynchronousInstallInProgress(ControllerContext context)
+ {
+ if (context.getMode() != ControllerMode.ASYNCHRONOUS)
+ return false;
+
+ return contextsInstalledByExecutor.isBeingInstalled(context);
+ }
+
+ /**
+ * A task being handled asyynchronously by the executor
+ *
+ */
+ abstract class InterruptibleControllerTask implements Runnable
+ {
+ /**
+ * The thread used to handle the asynchronous task
+ */
+ Thread thread;
+
+ /**
+ * True if the task is interrupted
+ */
+ volatile boolean interrupted;
+
+ /**
+ * Latch counted down by interrupted tasks once they have reached a state where they finish
+ */
+ CountDownLatch interruptedLatch;
+
+ /**
+ * Gets the thread that is currently used to install the asyncronous task
+ * @return The thread, or null if still queued in the executor
+ */
+ synchronized Thread getThread()
+ {
+ return thread;
+ }
+
+ /**
+ * Interrupt the task, and if associated with a thread
+ * return a countdown latch that will have a count of 0
+ * once the job has broken out
+ * @return the latch or null if not yet interrupted
+ */
+ synchronized CountDownLatch interrupt()
+ {
+ interrupted = true;
+ if (thread != null)
+ {
+ interruptedLatch = new CountDownLatch(1);
+ return interruptedLatch;
+ }
+ return null;
+ }
+
+ /**
+ * Check the interrupted status
+ * @return true if interrupted
+ */
+ boolean isInterrupted()
+ {
+ return interrupted;
+ }
+
+ /**
+ * Associate the current thread with the task, or clear it in contextsInstalledByExecutor
+ * if it has been interrupted. This should be the first thing tasks do once they run.
+ *
+ * @param context the context
+ * @return true if interrupted
+ */
+ synchronized boolean associateWithThreadOrDisassociateIfInterrupted(ControllerContext context)
+ {
+ if (interrupted)
+ {
+ contextsInstalledByExecutor.disassociateWithTask(context);
+ return true;
+ }
+ thread = Thread.currentThread();
+ return false;
+ }
+
+ /**
+ * Disassociate the thread with the task, and if interrupted count down the latch so those
+ * awaiting the latch know the task has finished.
+ */
+ synchronized void disassociateWithThreadAndSignalEnd()
+ {
+ thread = null;
+ if (interruptedLatch != null)
+ {
+ interruptedLatch.countDown();
+ }
+ }
+ }
+
+
+ /**
+ * Interruptible task used to install a controller context asynchronously.
+ * It will install the context as far as possible towards its required state,
+ * before resolving the other contexts.
+ */
+ class InstallControllerContextTask extends InterruptibleControllerTask
+ {
+ ControllerContext context;
+ ClassLoader classLoader;
+ boolean trace;
+
+ public InstallControllerContextTask(ControllerContext context, boolean trace)
+ {
+ this.context = context;
+ this.classLoader = SecurityActions.getContextClassLoader();
+ this.trace = trace;
+ }
+
+ public void run()
+ {
+ if (associateWithThreadOrDisassociateIfInterrupted(context))
+ return;
+
+ if (trace)
+ log.trace(Thread.currentThread().getName() + " starting asyncronous install of " + context.getName());
+
+ lockWrite();
+ ClassLoader tcl = SecurityActions.setContextClassLoader(classLoader);
+ try
+ {
+ //Move the given context as far through the states as possible
+ boolean stateChanged = false;
+ try
+ {
+ stateChanged = installMyContext();
+ }
+ finally
+ {
+ contextsInstalledByExecutor.disassociateWithTask(context);
+ }
+
+ //The given context had its state changed, now see if anybody was dependent on it
+ if (stateChanged && !interrupted)
+ {
+ resolveContexts(trace);
+ }
+ }
+ catch (Throwable t)
+ {
+ Object ctx = trace ? context : context.getName();
+ log.error("Problem installing context asynchronously " + ctx, t);
+ }
+ finally
+ {
+ if (trace)
+ log.trace(Thread.currentThread().getName() + " asynchronous install done for " + context.getName());
+ SecurityActions.resetContextClassLoader(tcl);
+ unlockWrite();
+
+ disassociateWithThreadAndSignalEnd();
+ }
+ }
+
+ boolean installMyContext()
+ {
+ boolean stateChanged = false;
+
+ if (!stateModel.isValidState(context.getRequiredState()))
+ throw new IllegalArgumentException("Unknown state: " + context.getRequiredState());
+
+ boolean resolved = true;
+
+ while(resolved && stateModel.isBeforeState(context.getState(), context.getRequiredState()) && !interrupted)
+ {
+ resolved = false;
+ ControllerState toState = stateModel.getNextState(context.getState());
+ if (advance(context))
+ {
+ try
+ {
+ if (resolveDependencies(context, toState))
+ {
+ resolved = true;
+ }
+ }
+ catch (Throwable error)
+ {
+ Object ctx = trace ? context : context.getName();
+ log.error("Error resolving dependencies for " + toState.getStateString() + ": " + ctx, error);
+ uninstallContext(context, stateModel.getInitialState(), trace);
+ errorContexts.put(context.getName(), context);
+ context.setError(error);
+ }
+
+ if (resolved)
+ {
+ resolved = incrementState(context, trace);
+ if (resolved)
+ {
+ stateChanged = true;
+ }
+ }
+ }
+ }
+
+ return stateChanged;
+ }
+ }
+
+
+
+ /**
+ * Class used to keep track of contexts that are scheduled for asynchronous install,
+ * or are in the process of being installed asynchronously.
+ *
+ */
+ private static class ContextsInstalledByExecutor
+ {
+ /** The contexts that are currently being installed by the executor */
+ Map<ControllerContext, InterruptibleControllerTask> executorTasksByContext = new ConcurrentHashMap<ControllerContext, InterruptibleControllerTask>();
+ /**
+ * Checks whether context should be installed asynchronously, by checking the controller mode and the current thread
+ * @param context The context
+ * @return Whether the context should be installed in the executor
+ */
+ boolean shouldInstallAsynchronously(ControllerContext context)
+ {
+ if (context.getMode() == ControllerMode.ASYNCHRONOUS)
+ {
+ final InterruptibleControllerTask task = executorTasksByContext.get(context);
+ return task == null || task.getThread() != Thread.currentThread();
+ }
+ return false;
+ }
+
+ /**
+ * Records the context and the asynchronous task to install it
+ * @param context The context to be installed asynchronously
+ * @param task The task that will be used to install the context
+ */
+ void markForTaskExecution(ControllerContext context, InterruptibleControllerTask task)
+ {
+ executorTasksByContext.put(context, task);
+ }
+
+ /**
+ * Removes the task that was used to install the context
+ * @param context The context whose task we want to remove
+ */
+ void disassociateWithTask(ControllerContext context)
+ {
+ executorTasksByContext.remove(context);
+ }
+
+ /**
+ * Checks if the context is recorded for asynchronous install, and if the thread used is different
+ * from the current thread.
+ * @param context The context to check
+ * @return true if installed by another thread
+ */
+ boolean isInstalledByOtherThread(ControllerContext context)
+ {
+ final InterruptibleControllerTask task = executorTasksByContext.get(context);
+ return task != null && Thread.currentThread() != task.getThread();
+ }
+
+ /**
+ * Checks in the context is recorded for asynchronous install
+ * @param context The context to check
+ * @return true if recorded for asynchronous install
+ */
+ boolean isBeingInstalled(ControllerContext context)
+ {
+ return executorTasksByContext.get(context) != null;
+ }
+
+ /**
+ * Checks if the passed in context is recorded for asynchronous install,
+ * and if it is interrupts the asynchronous task.<p>
+ *
+ * This method must be called with the write lock taken
+ *
+ * @param context The context to interrupt
+ * @param controller the controller
+ */
+ void interruptTaskAndBlock(ControllerContext context, AbstractController controller)
+ {
+ InterruptibleControllerTask task = executorTasksByContext.get(context);
+ if (task != null)
+ {
+ controller.unlockWrite();
+ try
+ {
+ CountDownLatch latch = task.interrupt();
+ if (latch != null)
+ {
+ try
+ {
+ latch.await();
+ }
+ catch(InterruptedException e)
+ {
+ Thread.currentThread().interrupt();
+ }
+ }
+ }
+ finally
+ {
+ controller.lockWrite();
+ }
+ }
+ }
+ }
+
+ // Context queries & registry
+
+ public Set<ControllerContext> filter(Iterable<ControllerContext> contexts, ContextFilter filter)
+ {
+ return registry.filter(contexts, filter);
+ }
+
+ public Set<ControllerContext> getInstantiatedContexts(Class<?> clazz)
+ {
+ return registry.getInstantiatedContexts(clazz);
+ }
+
+ public Set<ControllerContext> getContexts(Class<?> clazz, ControllerState state)
+ {
+ return registry.getContexts(clazz, state);
+ }
+
+ public ControllerContext getContextByClass(Class<?> clazz)
+ {
+ return registry.getContextByClass(clazz);
+ }
+
+ public void addInstantiatedContext(ControllerContext context)
+ {
+ registry.addInstantiatedContext(context);
+ }
+
+ public void registerInstantiatedContext(ControllerContext context, Class<?>... classes)
+ {
+ registry.registerInstantiatedContext(context, classes);
+ }
+
+ public void unregisterInstantiatedContext(ControllerContext context, Class<?>... classes)
+ {
+ registry.unregisterInstantiatedContext(context, classes);
+ }
+
+ public void removeInstantiatedContext(ControllerContext context)
+ {
+ registry.removeInstantiatedContext(context);
+ }
+
+ public Set<Class<?>> getExposedClasses(ControllerContext context)
+ {
+ return registry.getExposedClasses(context);
+ }
+
+
+ //New accessors for resolver
+ protected boolean isOnDemandEnabled()
+ {
+ return onDemandEnabled;
+ }
+
+ protected void setOnDemandEnabled(boolean onDemandEnabled)
+ {
+ this.onDemandEnabled = onDemandEnabled;
+ }
+
+
+}
Copied: projects/kernel/branches/resolver/kernel/src/test/java/org/jboss/test/kernel/dependency/support/ScopedTestUtil.java (from rev 99452, projects/kernel/trunk/kernel/src/test/java/org/jboss/test/kernel/dependency/support/ScopedTestUtil.java)
===================================================================
--- projects/kernel/branches/resolver/kernel/src/test/java/org/jboss/test/kernel/dependency/support/ScopedTestUtil.java (rev 0)
+++ projects/kernel/branches/resolver/kernel/src/test/java/org/jboss/test/kernel/dependency/support/ScopedTestUtil.java 2010-01-15 12:19:28 UTC (rev 99462)
@@ -0,0 +1,90 @@
+/*
+* 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.test.kernel.dependency.support;
+
+import java.net.URL;
+
+import org.jboss.beans.metadata.spi.BeanMetaData;
+import org.jboss.dependency.plugins.AbstractController;
+import org.jboss.dependency.spi.Controller;
+import org.jboss.dependency.spi.ControllerContext;
+import org.jboss.dependency.spi.ControllerState;
+import org.jboss.kernel.Kernel;
+import org.jboss.kernel.spi.dependency.KernelControllerContext;
+import org.jboss.kernel.spi.deployment.KernelDeployment;
+import org.jboss.test.kernel.AbstractKernelTest;
+
+/**
+ *
+ * @author <a href="kabir.khan at jboss.com">Kabir Khan</a>
+ * @version $Revision: 1.1 $
+ */
+public class ScopedTestUtil extends TestUtil
+{
+ public ScopedTestUtil(Kernel kernel, AbstractKernelTest test) throws Throwable
+ {
+ super(kernel, test);
+ }
+
+ @Override
+ public ControllerContext getContext(String name)
+ {
+ return searchForContext(name, null);
+ }
+
+ @Override
+ public ControllerContext getInstalledContext(String name) throws Throwable
+ {
+ return searchForContext(name, ControllerState.INSTALLED);
+ }
+
+ protected ControllerContext searchForContext(String name, ControllerState state)
+ {
+ Controller main = getKernel().getController();
+ if (main instanceof AbstractController == false)
+ throw new RuntimeException("Unknown controller type " + main);
+
+ AbstractController mainController = (AbstractController)getKernel().getController();
+ ControllerContext context = mainController.getContext(name, state);
+ if (context != null)
+ return context;
+
+ for (Controller controller : mainController.getControllers())
+ {
+ if (controller instanceof AbstractController == false)
+ throw new RuntimeException("Unknown controller type");
+ context = ((AbstractController)controller).getContext(name, state);
+ if (context != null)
+ return context;
+ }
+
+ return null;
+ }
+
+ @Override
+ public void uninstall(String name) throws Throwable
+ {
+ super.uninstall(name);
+ }
+
+
+}
Deleted: projects/kernel/branches/resolver/kernel/src/test/java/org/jboss/test/kernel/dependency/test/DependencyTestSuite.java
===================================================================
--- projects/kernel/trunk/kernel/src/test/java/org/jboss/test/kernel/dependency/test/DependencyTestSuite.java 2010-01-15 10:05:32 UTC (rev 99451)
+++ projects/kernel/branches/resolver/kernel/src/test/java/org/jboss/test/kernel/dependency/test/DependencyTestSuite.java 2010-01-15 12:19:28 UTC (rev 99462)
@@ -1,125 +0,0 @@
-/*
-* JBoss, Home of Professional Open Source
-* Copyright 2005, JBoss Inc., and individual contributors as indicated
-* by the @authors tag. See the copyright.txt in the distribution for a
-* full listing of individual contributors.
-*
-* This is free software; you can redistribute it and/or modify it
-* under the terms of the GNU Lesser General Public License as
-* published by the Free Software Foundation; either version 2.1 of
-* the License, or (at your option) any later version.
-*
-* This software is distributed in the hope that it will be useful,
-* but WITHOUT ANY WARRANTY; without even the implied warranty of
-* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-* Lesser General Public License for more details.
-*
-* You should have received a copy of the GNU Lesser General Public
-* License along with this software; if not, write to the Free
-* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
-* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
-*/
-package org.jboss.test.kernel.dependency.test;
-
-import junit.framework.Test;
-import junit.framework.TestSuite;
-import junit.textui.TestRunner;
-
-/**
- * Dependency Test Suite.
- *
- * @author <a href="adrian at jboss.com">Adrian Brock</a>
- * @version $Revision$
- */
-public class DependencyTestSuite extends TestSuite
-{
- public static void main(String[] args)
- {
- TestRunner.run(suite());
- }
-
- public static Test suite()
- {
- TestSuite suite = new TestSuite("Dependency Tests");
-
- suite.addTest(PlainDependencyTestCase.suite());
- suite.addTest(PlainDependencyXMLTestCase.suite());
- suite.addTest(PlainDependencyAnnotationTestCase.suite());
- suite.addTest(GenericBeanFactoryPlainDependencyTestCase.suite());
- suite.addTest(GenericBeanFactoryPlainDependencyXMLTestCase.suite());
- suite.addTest(OnDemandDependencyTestCase.suite());
- suite.addTest(OnDemandDependencyXMLTestCase.suite());
- suite.addTest(GenericBeanFactoryOnDemandDependencyTestCase.suite());
- suite.addTest(GenericBeanFactoryOnDemandDependencyXMLTestCase.suite());
- suite.addTest(PropertyDependencyTestCase.suite());
- suite.addTest(PropertyDependencyXMLTestCase.suite());
- suite.addTest(PropertyDependencyAnnotationTestCase.suite());
- suite.addTest(PropertyFieldDependencyTestCase.suite());
- suite.addTest(PropertyField2DependencyTestCase.suite());
- suite.addTest(GenericBeanFactoryPropertyDependencyTestCase.suite());
- suite.addTest(GenericBeanFactoryPropertyDependencyXMLTestCase.suite());
- suite.addTest(GenericBeanFactoryFieldPropertyDependencyTestCase.suite());
- suite.addTest(GenericBeanFactoryField2PropertyDependencyTestCase.suite());
- suite.addTest(ConstructorDependencyTestCase.suite());
- suite.addTest(ConstructorDependencyXMLTestCase.suite());
- suite.addTest(ConstructorDependencyAnnotationTestCase.suite());
- suite.addTest(GenericBeanFactoryConstructorDependencyTestCase.suite());
- suite.addTest(GenericBeanFactoryConstructorDependencyXMLTestCase.suite());
- suite.addTest(DemandDependencyTestCase.suite());
- suite.addTest(DemandDependencyXMLTestCase.suite());
- suite.addTest(DemandDependencyAnnotationTestCase.suite());
- suite.addTest(GenericBeanFactoryDemandDependencyTestCase.suite());
- suite.addTest(GenericBeanFactoryDemandDependencyXMLTestCase.suite());
- suite.addTest(PlainLifecycleDependencyTestCase.suite());
- suite.addTest(PlainLifecycleDependencyXMLTestCase.suite());
- suite.addTest(PlainLifecycleDependencyAnnotationTestCase.suite());
- suite.addTest(GenericBeanFactoryPlainLifecycleDependencyTestCase.suite());
- suite.addTest(GenericBeanFactoryPlainLifecycleDependencyXMLTestCase.suite());
- suite.addTest(ComplicatedLifecycleDependencyTestCase.suite());
- suite.addTest(ComplicatedLifecycleDependencyXMLTestCase.suite());
- suite.addTest(ComplicatedLifecycleDependencyAnnotationTestCase.suite());
- suite.addTest(KernelControllerContextAwareTestCase.suite());
- suite.addTest(KernelControllerContextAwareXMLTestCase.suite());
- suite.addTest(KernelControllerContextAwareAnnotationTestCase.suite());
- suite.addTest(InstallDependencyTestCase.suite());
- suite.addTest(InstallDependencyXMLTestCase.suite());
- suite.addTest(InstallDependencyAnnotationTestCase.suite());
- suite.addTest(GenericBeanFactoryInstallDependencyTestCase.suite());
- suite.addTest(GenericBeanFactoryInstallDependencyXMLTestCase.suite());
- suite.addTest(GenericBeanFactoryCallbackDependencyTestCase.suite());
- suite.addTest(GenericBeanFactoryCallbackDependencyXMLTestCase.suite());
- suite.addTest(InstallSelfDependencyTestCase.suite());
- suite.addTest(InstallSelfDependencyXMLTestCase.suite());
- suite.addTest(InstallSelfDependencyAnnotationTestCase.suite());
- suite.addTest(FromContextTestCase.suite());
- suite.addTest(FromContextXMLTestCase.suite());
- suite.addTest(FromContextAnnotationTestCase.suite());
- suite.addTest(PlainAliasTestCase.suite());
- suite.addTest(PlainAliasXMLTestCase.suite());
- suite.addTest(PlainAliasAnnotationTestCase.suite());
- suite.addTest(CallbackTestCase.suite());
- suite.addTest(CallbackXMLTestCase.suite());
- suite.addTest(CallbackAnnotationTestCase.suite());
- suite.addTest(CallbackCollectionTestCase.suite());
- suite.addTest(CallbackCollectionXMLTestCase.suite());
- suite.addTest(CallbackCollectionAnnotationTestCase.suite());
- suite.addTest(CallbackCollectionFieldsTestCase.suite());
- suite.addTest(CallbackCollectionFields2TestCase.suite());
- suite.addTest(MatcherDemandSupplyTestCase.suite());
- suite.addTest(MatcherDemandSupplyXMLTestCase.suite());
- suite.addTest(MatcherDemandSupplyAnnotationTestCase.suite());
- suite.addTest(NestedPropertyTestCase.suite());
- suite.addTest(NestedPropertyXMLTestCase.suite());
- suite.addTest(BeanValidatorBridgeTestCase.suite());
- suite.addTest(DuplicateAliasTestCase.suite());
- suite.addTest(DuplicateAliasXMLTestCase.suite());
- suite.addTest(DuplicateAliasAnnotationTestCase.suite());
- suite.addTest(ScopedDuplicateAliasTestCase.suite());
- suite.addTest(ScopedDuplicateAliasXMLTestCase.suite());
- suite.addTest(ScopedDuplicateAliasAnnotationTestCase.suite());
- suite.addTest(OptionalTestCase.suite());
- suite.addTest(OptionalXMLTestCase.suite());
- suite.addTest(OptionalAnnotationTestCase.suite());
- return suite;
- }
-}
Copied: projects/kernel/branches/resolver/kernel/src/test/java/org/jboss/test/kernel/dependency/test/DependencyTestSuite.java (from rev 99452, projects/kernel/trunk/kernel/src/test/java/org/jboss/test/kernel/dependency/test/DependencyTestSuite.java)
===================================================================
--- projects/kernel/branches/resolver/kernel/src/test/java/org/jboss/test/kernel/dependency/test/DependencyTestSuite.java (rev 0)
+++ projects/kernel/branches/resolver/kernel/src/test/java/org/jboss/test/kernel/dependency/test/DependencyTestSuite.java 2010-01-15 12:19:28 UTC (rev 99462)
@@ -0,0 +1,129 @@
+/*
+* JBoss, Home of Professional Open Source
+* Copyright 2005, JBoss Inc., and individual contributors as indicated
+* by the @authors tag. See the copyright.txt in the distribution for a
+* full listing of individual contributors.
+*
+* This is free software; you can redistribute it and/or modify it
+* under the terms of the GNU Lesser General Public License as
+* published by the Free Software Foundation; either version 2.1 of
+* the License, or (at your option) any later version.
+*
+* This software is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+* Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public
+* License along with this software; if not, write to the Free
+* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+*/
+package org.jboss.test.kernel.dependency.test;
+
+import junit.framework.Test;
+import junit.framework.TestSuite;
+import junit.textui.TestRunner;
+
+/**
+ * Dependency Test Suite.
+ *
+ * @author <a href="adrian at jboss.com">Adrian Brock</a>
+ * @version $Revision$
+ */
+public class DependencyTestSuite extends TestSuite
+{
+ public static void main(String[] args)
+ {
+ TestRunner.run(suite());
+ }
+
+ public static Test suite()
+ {
+ TestSuite suite = new TestSuite("Dependency Tests");
+
+ suite.addTest(PlainDependencyTestCase.suite());
+ suite.addTest(PlainDependencyXMLTestCase.suite());
+ suite.addTest(PlainDependencyAnnotationTestCase.suite());
+ suite.addTest(GenericBeanFactoryPlainDependencyTestCase.suite());
+ suite.addTest(GenericBeanFactoryPlainDependencyXMLTestCase.suite());
+ suite.addTest(OnDemandDependencyTestCase.suite());
+ suite.addTest(OnDemandDependencyXMLTestCase.suite());
+ suite.addTest(GenericBeanFactoryOnDemandDependencyTestCase.suite());
+ suite.addTest(GenericBeanFactoryOnDemandDependencyXMLTestCase.suite());
+ suite.addTest(PropertyDependencyTestCase.suite());
+ suite.addTest(PropertyDependencyXMLTestCase.suite());
+ suite.addTest(PropertyDependencyAnnotationTestCase.suite());
+ suite.addTest(PropertyFieldDependencyTestCase.suite());
+ suite.addTest(PropertyField2DependencyTestCase.suite());
+ suite.addTest(GenericBeanFactoryPropertyDependencyTestCase.suite());
+ suite.addTest(GenericBeanFactoryPropertyDependencyXMLTestCase.suite());
+ suite.addTest(GenericBeanFactoryFieldPropertyDependencyTestCase.suite());
+ suite.addTest(GenericBeanFactoryField2PropertyDependencyTestCase.suite());
+ suite.addTest(ConstructorDependencyTestCase.suite());
+ suite.addTest(ConstructorDependencyXMLTestCase.suite());
+ suite.addTest(ConstructorDependencyAnnotationTestCase.suite());
+ suite.addTest(GenericBeanFactoryConstructorDependencyTestCase.suite());
+ suite.addTest(GenericBeanFactoryConstructorDependencyXMLTestCase.suite());
+ suite.addTest(DemandDependencyTestCase.suite());
+ suite.addTest(DemandDependencyXMLTestCase.suite());
+ suite.addTest(DemandDependencyAnnotationTestCase.suite());
+ suite.addTest(GenericBeanFactoryDemandDependencyTestCase.suite());
+ suite.addTest(GenericBeanFactoryDemandDependencyXMLTestCase.suite());
+ suite.addTest(PlainLifecycleDependencyTestCase.suite());
+ suite.addTest(PlainLifecycleDependencyXMLTestCase.suite());
+ suite.addTest(PlainLifecycleDependencyAnnotationTestCase.suite());
+ suite.addTest(GenericBeanFactoryPlainLifecycleDependencyTestCase.suite());
+ suite.addTest(GenericBeanFactoryPlainLifecycleDependencyXMLTestCase.suite());
+ suite.addTest(ComplicatedLifecycleDependencyTestCase.suite());
+ suite.addTest(ComplicatedLifecycleDependencyXMLTestCase.suite());
+ suite.addTest(ComplicatedLifecycleDependencyAnnotationTestCase.suite());
+ suite.addTest(KernelControllerContextAwareTestCase.suite());
+ suite.addTest(KernelControllerContextAwareXMLTestCase.suite());
+ suite.addTest(KernelControllerContextAwareAnnotationTestCase.suite());
+ suite.addTest(InstallDependencyTestCase.suite());
+ suite.addTest(InstallDependencyXMLTestCase.suite());
+ suite.addTest(InstallDependencyAnnotationTestCase.suite());
+ suite.addTest(GenericBeanFactoryInstallDependencyTestCase.suite());
+ suite.addTest(GenericBeanFactoryInstallDependencyXMLTestCase.suite());
+ suite.addTest(GenericBeanFactoryCallbackDependencyTestCase.suite());
+ suite.addTest(GenericBeanFactoryCallbackDependencyXMLTestCase.suite());
+ suite.addTest(InstallSelfDependencyTestCase.suite());
+ suite.addTest(InstallSelfDependencyXMLTestCase.suite());
+ suite.addTest(InstallSelfDependencyAnnotationTestCase.suite());
+ suite.addTest(FromContextTestCase.suite());
+ suite.addTest(FromContextXMLTestCase.suite());
+ suite.addTest(FromContextAnnotationTestCase.suite());
+ suite.addTest(PlainAliasTestCase.suite());
+ suite.addTest(PlainAliasXMLTestCase.suite());
+ suite.addTest(PlainAliasAnnotationTestCase.suite());
+ suite.addTest(CallbackTestCase.suite());
+ suite.addTest(CallbackXMLTestCase.suite());
+ suite.addTest(CallbackAnnotationTestCase.suite());
+ suite.addTest(CallbackCollectionTestCase.suite());
+ suite.addTest(CallbackCollectionXMLTestCase.suite());
+ suite.addTest(CallbackCollectionAnnotationTestCase.suite());
+ suite.addTest(CallbackCollectionFieldsTestCase.suite());
+ suite.addTest(CallbackCollectionFields2TestCase.suite());
+ suite.addTest(MatcherDemandSupplyTestCase.suite());
+ suite.addTest(MatcherDemandSupplyXMLTestCase.suite());
+ suite.addTest(MatcherDemandSupplyAnnotationTestCase.suite());
+ suite.addTest(NestedPropertyTestCase.suite());
+ suite.addTest(NestedPropertyXMLTestCase.suite());
+ suite.addTest(BeanValidatorBridgeTestCase.suite());
+ suite.addTest(DuplicateAliasTestCase.suite());
+ suite.addTest(DuplicateAliasXMLTestCase.suite());
+ suite.addTest(DuplicateAliasAnnotationTestCase.suite());
+ suite.addTest(ScopedDuplicateAliasTestCase.suite());
+ suite.addTest(ScopedDuplicateAliasXMLTestCase.suite());
+ suite.addTest(ScopedDuplicateAliasAnnotationTestCase.suite());
+ suite.addTest(OnDemandDependencyTestCase.suite());
+ suite.addTest(OnDemandDependencyXMLTestCase.suite());
+ suite.addTest(ScopedOnDemandDependencyTestCase.suite());
+ suite.addTest(ScopedOnDemandDependencyXMLTestCase.suite());
+ suite.addTest(OptionalTestCase.suite());
+ suite.addTest(OptionalXMLTestCase.suite());
+ suite.addTest(OptionalAnnotationTestCase.suite());
+ return suite;
+ }
+}
Deleted: projects/kernel/branches/resolver/kernel/src/test/java/org/jboss/test/kernel/dependency/test/OldAbstractKernelDependencyTest.java
===================================================================
--- projects/kernel/trunk/kernel/src/test/java/org/jboss/test/kernel/dependency/test/OldAbstractKernelDependencyTest.java 2010-01-15 10:05:32 UTC (rev 99451)
+++ projects/kernel/branches/resolver/kernel/src/test/java/org/jboss/test/kernel/dependency/test/OldAbstractKernelDependencyTest.java 2010-01-15 12:19:28 UTC (rev 99462)
@@ -1,207 +0,0 @@
-/*
-* JBoss, Home of Professional Open Source
-* Copyright 2005, JBoss Inc., and individual contributors as indicated
-* by the @authors tag. See the copyright.txt in the distribution for a
-* full listing of individual contributors.
-*
-* This is free software; you can redistribute it and/or modify it
-* under the terms of the GNU Lesser General Public License as
-* published by the Free Software Foundation; either version 2.1 of
-* the License, or (at your option) any later version.
-*
-* This software is distributed in the hope that it will be useful,
-* but WITHOUT ANY WARRANTY; without even the implied warranty of
-* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-* Lesser General Public License for more details.
-*
-* You should have received a copy of the GNU Lesser General Public
-* License along with this software; if not, write to the Free
-* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
-* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
-*/
-package org.jboss.test.kernel.dependency.test;
-
-import java.net.URL;
-import java.util.Set;
-import java.util.HashSet;
-import java.util.List;
-
-import org.jboss.beans.metadata.spi.BeanMetaData;
-import org.jboss.beans.metadata.spi.PropertyMetaData;
-import org.jboss.beans.metadata.spi.factory.GenericBeanFactoryMetaData;
-import org.jboss.dependency.spi.ControllerContext;
-import org.jboss.dependency.spi.ControllerState;
-import org.jboss.kernel.Kernel;
-import org.jboss.test.kernel.AbstractKernelTest;
-import org.jboss.test.kernel.dependency.support.TestUtil;
-import org.jboss.util.Classes;
-
-/**
- * An abstract kernel config test.
- *
- * @author <a href="adrian at jboss.com">Adrian Brock</a>
- * @version $Revision$
- */
-public class OldAbstractKernelDependencyTest extends AbstractKernelTest
-{
- /** The test utility */
- private TestUtil util;
-
- /** Whether this is an xml test */
- private boolean xmltest;
-
- /** The BeanMetaDatas */
- private BeanMetaData[] beanMetaDatas;
-
- public OldAbstractKernelDependencyTest(String name) throws Throwable
- {
- this(name, false);
- }
-
- public OldAbstractKernelDependencyTest(String name, boolean xmltest) throws Throwable
- {
- super(name);
- this.xmltest = xmltest;
- }
-
- protected void setUp() throws Exception
- {
- super.setUp();
- try
- {
- Kernel kernel = bootstrap();
- this.util = new TestUtil(kernel, this);
- }
- catch (Exception e)
- {
- throw e;
- }
- catch (Throwable t)
- {
- throw new RuntimeException(t);
- }
- }
-
- protected TestUtil getUtil()
- {
- return util;
- }
-
- protected ControllerContext install(int number, String name) throws Throwable
- {
- if (xmltest)
- {
- deploy(number);
- return util.getContext(name);
- }
- else
- {
- return util.install(beanMetaDatas[number]);
- }
- }
-
- protected void uninstall(String name) throws Throwable
- {
- util.uninstall(name);
- }
-
- protected ControllerContext assertInstall(int number, String name) throws Throwable
- {
- ControllerContext result = assertInstall(number, name, ControllerState.INSTALLED);
- assertContext(name);
- return result;
- }
-
- protected ControllerContext assertInstall(int number, String name, ControllerState expected) throws Throwable
- {
- ControllerContext context = install(number, name);
- assertNotNull(context);
- assertEquals(expected, context.getState());
- return context;
- }
-
- protected ControllerContext assertContext(String name) throws Throwable
- {
- return assertContext(name, ControllerState.INSTALLED);
- }
-
- protected ControllerContext assertContext(String name, ControllerState expected) throws Throwable
- {
- ControllerContext context = util.getContext(name);
- assertNotNull("Expected " + name + " state=" + expected.toShortString(), context);
- assertEquals(expected, context.getState());
- return context;
- }
-
- protected void assertUninstall(String name) throws Throwable
- {
- uninstall(name);
-
- assertNotInstalled(name);
-
- ControllerContext context = util.getContext(name);
- assertNull(context);
- }
-
- protected void assertNotInstalled(String name) throws Throwable
- {
- if (util.getInstalledContext(name) != null)
- fail("Should not be installed");
- }
-
- protected void setBeanMetaDatas(BeanMetaData[] beanMetaDatas)
- {
- if (xmltest)
- return;
- this.beanMetaDatas = beanMetaDatas;
- }
-
- protected void addBeanProperty(GenericBeanFactoryMetaData factory, PropertyMetaData property)
- {
- Set<PropertyMetaData> propertys = factory.getProperties();
- if (propertys == null)
- {
- propertys = new HashSet<PropertyMetaData>();
- factory.setProperties(propertys);
- }
- propertys.add(property);
- }
-
- protected BeanMetaData getBeanMetaData(GenericBeanFactoryMetaData factory)
- {
- List<BeanMetaData> beans = factory.getBeans();
- assertNotNull(beans);
- assertEquals(1, beans.size());
- return beans.get(0);
- }
-
- protected String createName(int number)
- {
- String packageName = Classes.getPackageName(getClass());
- packageName = packageName.replace('.', '/');
- return "/xml-test/" + packageName + '/' + getName() + number + ".xml";
- }
-
- protected void deploy(int number) throws Throwable
- {
- String name = createName(number);
- getLog().debug("Using " + name);
- URL url = getResource(name);
- if (url == null)
- throw new RuntimeException("Resource not found: " + name);
- getLog().debug("url=" + url);
- util.deploy(url);
-
- }
-
- protected void configureLoggingAfterBootstrap()
- {
- //enableTrace("org.jboss.beans");
- //enableTrace("org.jboss.dependency");
- //enableTrace("org.jboss.joinpoint.plugins.config");
- //enableTrace("org.jboss.kernel.plugins.config");
- //enableTrace("org.jboss.kernel.plugins.dependency");
- //if (xmltest)
- // enableTrace("org.jboss.xb");
- }
-}
Copied: projects/kernel/branches/resolver/kernel/src/test/java/org/jboss/test/kernel/dependency/test/OldAbstractKernelDependencyTest.java (from rev 99452, projects/kernel/trunk/kernel/src/test/java/org/jboss/test/kernel/dependency/test/OldAbstractKernelDependencyTest.java)
===================================================================
--- projects/kernel/branches/resolver/kernel/src/test/java/org/jboss/test/kernel/dependency/test/OldAbstractKernelDependencyTest.java (rev 0)
+++ projects/kernel/branches/resolver/kernel/src/test/java/org/jboss/test/kernel/dependency/test/OldAbstractKernelDependencyTest.java 2010-01-15 12:19:28 UTC (rev 99462)
@@ -0,0 +1,229 @@
+/*
+* JBoss, Home of Professional Open Source
+* Copyright 2005, JBoss Inc., and individual contributors as indicated
+* by the @authors tag. See the copyright.txt in the distribution for a
+* full listing of individual contributors.
+*
+* This is free software; you can redistribute it and/or modify it
+* under the terms of the GNU Lesser General Public License as
+* published by the Free Software Foundation; either version 2.1 of
+* the License, or (at your option) any later version.
+*
+* This software is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+* Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public
+* License along with this software; if not, write to the Free
+* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+*/
+package org.jboss.test.kernel.dependency.test;
+
+import java.net.URL;
+import java.util.Set;
+import java.util.HashSet;
+import java.util.List;
+
+import org.jboss.beans.metadata.spi.BeanMetaData;
+import org.jboss.beans.metadata.spi.PropertyMetaData;
+import org.jboss.beans.metadata.spi.factory.GenericBeanFactoryMetaData;
+import org.jboss.dependency.spi.ControllerContext;
+import org.jboss.dependency.spi.ControllerState;
+import org.jboss.kernel.Kernel;
+import org.jboss.test.kernel.AbstractKernelTest;
+import org.jboss.test.kernel.dependency.support.ScopedTestUtil;
+import org.jboss.test.kernel.dependency.support.TestUtil;
+import org.jboss.util.Classes;
+
+/**
+ * An abstract kernel config test.
+ *
+ * @author <a href="adrian at jboss.com">Adrian Brock</a>
+ * @version $Revision$
+ */
+public class OldAbstractKernelDependencyTest extends AbstractKernelTest
+{
+ /** The test utility */
+ private TestUtil util;
+
+ /** Whether this is an xml test */
+ private boolean xmlTest;
+
+ /** Whether this test uses scoped controllers */
+ private boolean scoped;
+
+ /** The BeanMetaDatas */
+ private BeanMetaData[] beanMetaDatas;
+
+ public OldAbstractKernelDependencyTest(String name) throws Throwable
+ {
+ this(name, false, false);
+ }
+
+ public OldAbstractKernelDependencyTest(String name, boolean xmltest) throws Throwable
+ {
+ this(name, xmltest, false);
+ }
+
+ public OldAbstractKernelDependencyTest(String name, boolean xmlTest, boolean scoped)
+ {
+ super(name);
+ this.xmlTest = xmlTest;
+ this.scoped = scoped;
+ }
+
+ protected void setUp() throws Exception
+ {
+ super.setUp();
+ try
+ {
+ Kernel kernel = bootstrap();
+ if (scoped)
+ this.util = new ScopedTestUtil(kernel, this);
+ else
+ this.util = new TestUtil(kernel, this);
+ }
+ catch (Exception e)
+ {
+ throw e;
+ }
+ catch (Throwable t)
+ {
+ throw new RuntimeException(t);
+ }
+ }
+
+ protected TestUtil getUtil()
+ {
+ return util;
+ }
+
+ protected ControllerContext install(int number, String name) throws Throwable
+ {
+ if (xmlTest)
+ {
+ deploy(number);
+ return util.getContext(name);
+ }
+ else
+ {
+ return util.install(beanMetaDatas[number]);
+ }
+ }
+
+ protected void uninstall(String name) throws Throwable
+ {
+ util.uninstall(name);
+ }
+
+ protected ControllerContext assertInstall(int number, String name) throws Throwable
+ {
+ ControllerContext result = assertInstall(number, name, ControllerState.INSTALLED);
+ assertContext(name);
+ return result;
+ }
+
+ protected ControllerContext assertInstall(int number, String name, ControllerState expected) throws Throwable
+ {
+ ControllerContext context = install(number, name);
+ assertNotNull(context);
+ assertEquals(expected, context.getState());
+ return context;
+ }
+
+ protected ControllerContext assertContext(String name) throws Throwable
+ {
+ return assertContext(name, ControllerState.INSTALLED);
+ }
+
+ protected ControllerContext assertContext(String name, ControllerState expected) throws Throwable
+ {
+ ControllerContext context = util.getContext(name);
+ assertNotNull("Expected " + name + " state=" + expected.toShortString(), context);
+ assertEquals(expected, context.getState());
+ return context;
+ }
+
+ protected void assertUninstall(String name) throws Throwable
+ {
+ uninstall(name);
+
+ assertNotInstalled(name);
+
+ ControllerContext context = util.getContext(name);
+ assertNull(context);
+ }
+
+ protected void assertNotInstalled(String name) throws Throwable
+ {
+ if (util.getInstalledContext(name) != null)
+ fail("Should not be installed");
+ }
+
+ protected void setBeanMetaDatas(BeanMetaData[] beanMetaDatas)
+ {
+ if (xmlTest)
+ return;
+ this.beanMetaDatas = beanMetaDatas;
+ }
+
+ protected void addBeanProperty(GenericBeanFactoryMetaData factory, PropertyMetaData property)
+ {
+ Set<PropertyMetaData> propertys = factory.getProperties();
+ if (propertys == null)
+ {
+ propertys = new HashSet<PropertyMetaData>();
+ factory.setProperties(propertys);
+ }
+ propertys.add(property);
+ }
+
+ protected BeanMetaData getBeanMetaData(GenericBeanFactoryMetaData factory)
+ {
+ List<BeanMetaData> beans = factory.getBeans();
+ assertNotNull(beans);
+ assertEquals(1, beans.size());
+ return beans.get(0);
+ }
+
+ protected String createName(int number)
+ {
+ String packageName = Classes.getPackageName(getClass());
+ packageName = packageName.replace('.', '/');
+ return "/xml-test/" + packageName + '/' + getName() + number + ".xml";
+ }
+
+ protected void deploy(int number) throws Throwable
+ {
+ String name = createName(number);
+ getLog().debug("Using " + name);
+ URL url = getResource(name);
+ if (url == null)
+ throw new RuntimeException("Resource not found: " + name);
+ getLog().debug("url=" + url);
+ util.deploy(url);
+
+ }
+
+ protected void configureLoggingAfterBootstrap()
+ {
+ //enableTrace("org.jboss.beans");
+ //enableTrace("org.jboss.dependency");
+ //enableTrace("org.jboss.joinpoint.plugins.config");
+ //enableTrace("org.jboss.kernel.plugins.config");
+ //enableTrace("org.jboss.kernel.plugins.dependency");
+ //if (xmltest)
+ // enableTrace("org.jboss.xb");
+ }
+
+ /**
+ * Get the xmltest
+ * @return the xmltest
+ */
+ public boolean isXmlTest()
+ {
+ return xmlTest;
+ }
+}
Deleted: projects/kernel/branches/resolver/kernel/src/test/java/org/jboss/test/kernel/dependency/test/OnDemandDependencyTestCase.java
===================================================================
--- projects/kernel/trunk/kernel/src/test/java/org/jboss/test/kernel/dependency/test/OnDemandDependencyTestCase.java 2010-01-15 10:05:32 UTC (rev 99451)
+++ projects/kernel/branches/resolver/kernel/src/test/java/org/jboss/test/kernel/dependency/test/OnDemandDependencyTestCase.java 2010-01-15 12:19:28 UTC (rev 99462)
@@ -1,252 +0,0 @@
-/*
-* JBoss, Home of Professional Open Source
-* Copyright 2005, JBoss Inc., and individual contributors as indicated
-* by the @authors tag. See the copyright.txt in the distribution for a
-* full listing of individual contributors.
-*
-* This is free software; you can redistribute it and/or modify it
-* under the terms of the GNU Lesser General Public License as
-* published by the Free Software Foundation; either version 2.1 of
-* the License, or (at your option) any later version.
-*
-* This software is distributed in the hope that it will be useful,
-* but WITHOUT ANY WARRANTY; without even the implied warranty of
-* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-* Lesser General Public License for more details.
-*
-* You should have received a copy of the GNU Lesser General Public
-* License along with this software; if not, write to the Free
-* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
-* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
-*/
-package org.jboss.test.kernel.dependency.test;
-
-import java.util.HashSet;
-
-import junit.framework.Test;
-
-import org.jboss.beans.metadata.plugins.AbstractBeanMetaData;
-import org.jboss.beans.metadata.plugins.AbstractDependencyValueMetaData;
-import org.jboss.beans.metadata.plugins.AbstractPropertyMetaData;
-import org.jboss.beans.metadata.spi.BeanMetaData;
-import org.jboss.beans.metadata.spi.PropertyMetaData;
-import org.jboss.dependency.spi.ControllerContext;
-import org.jboss.dependency.spi.ControllerMode;
-import org.jboss.dependency.spi.ControllerState;
-import org.jboss.test.kernel.dependency.support.SimpleBean;
-import org.jboss.test.kernel.dependency.support.SimpleBeanImpl;
-import org.jboss.test.kernel.dependency.support.SimpleBeanWithDependency;
-import org.jboss.test.kernel.dependency.support.SimpleBeanWithDependencyImpl;
-
-/**
- * OnDemand Dependency Test Case.
- *
- * @author <a href="adrian at jboss.com">Adrian Brock</a>
- * @version $Revision$
- */
-public class OnDemandDependencyTestCase extends OldAbstractKernelDependencyTest
-{
- public static Test suite()
- {
- return suite(OnDemandDependencyTestCase.class);
- }
-
- public OnDemandDependencyTestCase(String name) throws Throwable
- {
- super(name);
- }
-
- public OnDemandDependencyTestCase(String name, boolean xmltest) throws Throwable
- {
- super(name, xmltest);
- }
-
- public void testOnDemandDependencyOnDemandFirst() throws Throwable
- {
- onDemandDependencyOnDemandFirst();
-
- ControllerContext context1 = assertInstall(0, "Name1", ControllerState.DESCRIBED);
- ControllerContext context2 = assertInstall(1, "Name2");
- assertContext("Name1");
-
- SimpleBean bean1 = (SimpleBean) context1.getTarget();
- assertNotNull(bean1);
- assertEquals("String1", bean1.getString());
-
- SimpleBeanWithDependency bean2 = (SimpleBeanWithDependency) context2.getTarget();
- assertNotNull(bean2);
- assertEquals("String2", bean2.getString());
- assertEquals(bean1, bean2.getSimpleBean());
- }
-
- public void onDemandDependencyOnDemandFirst() throws Throwable
- {
- buildMetaData();
- }
-
- public void testOnDemandDependencyOnDemandSecond() throws Throwable
- {
- onDemandDependencyOnDemandSecond();
-
- ControllerContext context2 = assertInstall(1, "Name2", ControllerState.INSTANTIATED);
- ControllerContext context1 = assertInstall(0, "Name1");
- assertEquals(ControllerState.INSTALLED, context2.getState());
-
- SimpleBean bean1 = (SimpleBean) context1.getTarget();
- assertNotNull(bean1);
- assertEquals("String1", bean1.getString());
-
- SimpleBeanWithDependency bean2 = (SimpleBeanWithDependency) context2.getTarget();
- assertNotNull(bean2);
- assertEquals("String2", bean2.getString());
- assertEquals(bean1, bean2.getSimpleBean());
- }
-
- public void onDemandDependencyOnDemandSecond() throws Throwable
- {
- buildMetaData();
- }
-
- public void testOnDemandDependencyReinstall() throws Throwable
- {
- onDemandDependencyReinstall();
-
- ControllerContext context1 = assertInstall(0, "Name1", ControllerState.DESCRIBED);
- ControllerContext context2 = assertInstall(1, "Name2");
- ControllerContext context3 = assertInstall(2, "Name3");
- assertContext("Name1");
-
- SimpleBean bean1 = (SimpleBean) context1.getTarget();
- assertNotNull(bean1);
- assertEquals("String1", bean1.getString());
-
- SimpleBeanWithDependency bean2 = (SimpleBeanWithDependency) context2.getTarget();
- assertNotNull(bean2);
- assertEquals("String2", bean2.getString());
- assertEquals(bean1, bean2.getSimpleBean());
-
- SimpleBeanWithDependency bean3 = (SimpleBeanWithDependency) context3.getTarget();
- assertNotNull(bean3);
- assertEquals("String3", bean3.getString());
- assertEquals(bean1, bean3.getSimpleBean());
-
- assertUninstall("Name1");
-
- assertEquals(ControllerState.ERROR, context1.getState());
- assertEquals(ControllerState.INSTANTIATED, context2.getState());
- assertNotInstalled("Name2");
- assertEquals(ControllerState.INSTANTIATED, context3.getState());
- assertNotInstalled("Name3");
-
- context2 = assertContext("Name2", ControllerState.INSTANTIATED);
- context3 = assertContext("Name3", ControllerState.INSTANTIATED);
-
- context1 = assertInstall(0, "Name1");
- assertEquals(ControllerState.INSTALLED, context2.getState());
- assertEquals(ControllerState.INSTALLED, context3.getState());
-
- bean1 = (SimpleBean) context1.getTarget();
- assertNotNull(bean1);
- assertEquals("String1", bean1.getString());
-
- bean2 = (SimpleBeanWithDependency) context2.getTarget();
- assertNotNull(bean2);
- assertEquals("String2", bean2.getString());
- assertEquals(bean1, bean2.getSimpleBean());
-
- bean3 = (SimpleBeanWithDependency) context3.getTarget();
- assertNotNull(bean3);
- assertEquals("String3", bean3.getString());
- assertEquals(bean1, bean3.getSimpleBean());
-
- assertUninstall("Name2");
-
- context1 = assertContext("Name1");
- bean1 = (SimpleBean) context1.getTarget();
- assertNotNull(bean1);
- assertEquals("String1", bean1.getString());
-
- context3 = assertContext("Name3");
- bean3 = (SimpleBeanWithDependency) context3.getTarget();
- assertNotNull(bean3);
- assertEquals("String3", bean3.getString());
- assertEquals(bean1, bean3.getSimpleBean());
-
- context2 = assertInstall(1, "Name2");
-
- bean1 = (SimpleBean) context1.getTarget();
- assertNotNull(bean1);
- assertEquals("String1", bean1.getString());
-
- bean2 = (SimpleBeanWithDependency) context2.getTarget();
- assertNotNull(bean2);
- assertEquals("String2", bean2.getString());
- assertEquals(bean1, bean2.getSimpleBean());
-
- bean3 = (SimpleBeanWithDependency) context3.getTarget();
- assertNotNull(bean3);
- assertEquals("String3", bean3.getString());
- assertEquals(bean1, bean3.getSimpleBean());
-
- assertUninstall("Name2");
- context1 = assertContext("Name1");
- bean1 = (SimpleBean) context1.getTarget();
- assertNotNull(bean1);
- assertEquals("String1", bean1.getString());
-
- context3 = assertContext("Name3");
- bean3 = (SimpleBeanWithDependency) context3.getTarget();
- assertNotNull(bean3);
- assertEquals("String3", bean3.getString());
- assertEquals(bean1, bean3.getSimpleBean());
-
- assertUninstall("Name3");
- context1 = assertContext("Name1", ControllerState.DESCRIBED);
- assertNull(context1.getTarget());
-
- context2 = assertInstall(1, "Name2");
-
- bean1 = (SimpleBean) context1.getTarget();
- assertNotNull(bean1);
- assertEquals("String1", bean1.getString());
-
- bean2 = (SimpleBeanWithDependency) context2.getTarget();
- assertNotNull(bean2);
- assertEquals("String2", bean2.getString());
- assertEquals(bean1, bean2.getSimpleBean());
-
- context3 = assertInstall(2, "Name3");
- bean3 = (SimpleBeanWithDependency) context3.getTarget();
- assertNotNull(bean3);
- assertEquals("String3", bean3.getString());
- assertEquals(bean1, bean3.getSimpleBean());
- }
-
- public void onDemandDependencyReinstall() throws Throwable
- {
- buildMetaData();
- }
-
- protected void buildMetaData()
- {
- AbstractBeanMetaData metaData1 = new AbstractBeanMetaData("Name1", SimpleBeanImpl.class.getName());
- metaData1.setMode(ControllerMode.ON_DEMAND);
- HashSet<PropertyMetaData> attributes1 = new HashSet<PropertyMetaData>();
- attributes1.add(new AbstractPropertyMetaData("string", "String1"));
- metaData1.setProperties(attributes1);
-
- AbstractBeanMetaData metaData2 = new AbstractBeanMetaData("Name2", SimpleBeanWithDependencyImpl.class.getName());
- HashSet<PropertyMetaData> attributes2 = new HashSet<PropertyMetaData>();
- attributes2.add(new AbstractPropertyMetaData("string", "String2"));
- attributes2.add(new AbstractPropertyMetaData("simpleBean", new AbstractDependencyValueMetaData("Name1")));
- metaData2.setProperties(attributes2);
-
- AbstractBeanMetaData metaData3 = new AbstractBeanMetaData("Name3", SimpleBeanWithDependencyImpl.class.getName());
- HashSet<PropertyMetaData> attributes3 = new HashSet<PropertyMetaData>();
- attributes3.add(new AbstractPropertyMetaData("string", "String3"));
- attributes3.add(new AbstractPropertyMetaData("simpleBean", new AbstractDependencyValueMetaData("Name1")));
- metaData3.setProperties(attributes3);
-
- setBeanMetaDatas(new BeanMetaData[] { metaData1, metaData2, metaData3});
- }
-}
\ No newline at end of file
Copied: projects/kernel/branches/resolver/kernel/src/test/java/org/jboss/test/kernel/dependency/test/OnDemandDependencyTestCase.java (from rev 99452, projects/kernel/trunk/kernel/src/test/java/org/jboss/test/kernel/dependency/test/OnDemandDependencyTestCase.java)
===================================================================
--- projects/kernel/branches/resolver/kernel/src/test/java/org/jboss/test/kernel/dependency/test/OnDemandDependencyTestCase.java (rev 0)
+++ projects/kernel/branches/resolver/kernel/src/test/java/org/jboss/test/kernel/dependency/test/OnDemandDependencyTestCase.java 2010-01-15 12:19:28 UTC (rev 99462)
@@ -0,0 +1,285 @@
+/*
+* JBoss, Home of Professional Open Source
+* Copyright 2005, JBoss Inc., and individual contributors as indicated
+* by the @authors tag. See the copyright.txt in the distribution for a
+* full listing of individual contributors.
+*
+* This is free software; you can redistribute it and/or modify it
+* under the terms of the GNU Lesser General Public License as
+* published by the Free Software Foundation; either version 2.1 of
+* the License, or (at your option) any later version.
+*
+* This software is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+* Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public
+* License along with this software; if not, write to the Free
+* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+*/
+package org.jboss.test.kernel.dependency.test;
+
+import java.util.HashSet;
+import java.util.Set;
+
+import junit.framework.Test;
+
+import org.jboss.beans.metadata.plugins.AbstractAnnotationMetaData;
+import org.jboss.beans.metadata.plugins.AbstractBeanMetaData;
+import org.jboss.beans.metadata.plugins.AbstractDependencyValueMetaData;
+import org.jboss.beans.metadata.plugins.AbstractPropertyMetaData;
+import org.jboss.beans.metadata.spi.AnnotationMetaData;
+import org.jboss.beans.metadata.spi.BeanMetaData;
+import org.jboss.beans.metadata.spi.PropertyMetaData;
+import org.jboss.dependency.spi.ControllerContext;
+import org.jboss.dependency.spi.ControllerMode;
+import org.jboss.dependency.spi.ControllerState;
+import org.jboss.metadata.plugins.scope.DeploymentScope;
+import org.jboss.test.kernel.dependency.support.SimpleBean;
+import org.jboss.test.kernel.dependency.support.SimpleBeanImpl;
+import org.jboss.test.kernel.dependency.support.SimpleBeanWithDependency;
+import org.jboss.test.kernel.dependency.support.SimpleBeanWithDependencyImpl;
+
+/**
+ * OnDemand Dependency Test Case.
+ *
+ * @author <a href="adrian at jboss.com">Adrian Brock</a>
+ * @version $Revision$
+ */
+public class OnDemandDependencyTestCase extends OldAbstractKernelDependencyTest
+{
+ public static Test suite()
+ {
+ return suite(OnDemandDependencyTestCase.class);
+ }
+
+ public OnDemandDependencyTestCase(String name) throws Throwable
+ {
+ super(name);
+ }
+
+ public OnDemandDependencyTestCase(String name, boolean xmltest, boolean scoped) throws Throwable
+ {
+ super(name, xmltest, scoped);
+ }
+
+ public void testOnDemandDependencyOnDemandFirst() throws Throwable
+ {
+ onDemandDependencyOnDemandFirst();
+
+ ControllerContext context1 = assertInstall(offSetNumber(0), "Name1", ControllerState.DESCRIBED);
+ ControllerContext context2 = assertInstall(offSetNumber(1), "Name2");
+ assertContext("Name1");
+
+ assertControllers(context1, context2);
+
+ SimpleBean bean1 = (SimpleBean) context1.getTarget();
+ assertNotNull(bean1);
+ assertEquals("String1", bean1.getString());
+
+ SimpleBeanWithDependency bean2 = (SimpleBeanWithDependency) context2.getTarget();
+ assertNotNull(bean2);
+ assertEquals("String2", bean2.getString());
+ assertEquals(bean1, bean2.getSimpleBean());
+ }
+
+ public void onDemandDependencyOnDemandFirst() throws Throwable
+ {
+ buildMetaData();
+ }
+
+ public void testOnDemandDependencyOnDemandSecond() throws Throwable
+ {
+ onDemandDependencyOnDemandSecond();
+
+ ControllerContext context2 = assertInstall(offSetNumber(1), "Name2", ControllerState.INSTANTIATED);
+ ControllerContext context1 = assertInstall(offSetNumber(0), "Name1");
+ assertEquals(ControllerState.INSTALLED, context2.getState());
+
+ assertControllers(context1, context2);
+
+ SimpleBean bean1 = (SimpleBean) context1.getTarget();
+ assertNotNull(bean1);
+ assertEquals("String1", bean1.getString());
+
+ SimpleBeanWithDependency bean2 = (SimpleBeanWithDependency) context2.getTarget();
+ assertNotNull(bean2);
+ assertEquals("String2", bean2.getString());
+ assertEquals(bean1, bean2.getSimpleBean());
+ }
+
+ public void onDemandDependencyOnDemandSecond() throws Throwable
+ {
+ buildMetaData();
+ }
+
+ public void testOnDemandDependencyReinstall() throws Throwable
+ {
+ onDemandDependencyReinstall();
+
+ ControllerContext context1 = assertInstall(offSetNumber(0), "Name1", ControllerState.DESCRIBED);
+ ControllerContext context2 = assertInstall(offSetNumber(1), "Name2");
+ ControllerContext context3 = assertInstall(offSetNumber(2), "Name3");
+ assertContext("Name1");
+
+ assertControllers(context1, context2, context3);
+
+ SimpleBean bean1 = (SimpleBean) context1.getTarget();
+ assertNotNull(bean1);
+ assertEquals("String1", bean1.getString());
+
+ SimpleBeanWithDependency bean2 = (SimpleBeanWithDependency) context2.getTarget();
+ assertNotNull(bean2);
+ assertEquals("String2", bean2.getString());
+ assertEquals(bean1, bean2.getSimpleBean());
+
+ SimpleBeanWithDependency bean3 = (SimpleBeanWithDependency) context3.getTarget();
+ assertNotNull(bean3);
+ assertEquals("String3", bean3.getString());
+ assertEquals(bean1, bean3.getSimpleBean());
+
+ assertUninstall("Name1");
+
+ assertEquals(ControllerState.ERROR, context1.getState());
+ assertEquals(ControllerState.INSTANTIATED, context2.getState());
+ assertNotInstalled("Name2");
+ assertEquals(ControllerState.INSTANTIATED, context3.getState());
+ assertNotInstalled("Name3");
+
+ context2 = assertContext("Name2", ControllerState.INSTANTIATED);
+ context3 = assertContext("Name3", ControllerState.INSTANTIATED);
+
+ context1 = assertInstall(offSetNumber(0), "Name1");
+ assertEquals(ControllerState.INSTALLED, context2.getState());
+ assertEquals(ControllerState.INSTALLED, context3.getState());
+
+ bean1 = (SimpleBean) context1.getTarget();
+ assertNotNull(bean1);
+ assertEquals("String1", bean1.getString());
+
+ bean2 = (SimpleBeanWithDependency) context2.getTarget();
+ assertNotNull(bean2);
+ assertEquals("String2", bean2.getString());
+ assertEquals(bean1, bean2.getSimpleBean());
+
+ bean3 = (SimpleBeanWithDependency) context3.getTarget();
+ assertNotNull(bean3);
+ assertEquals("String3", bean3.getString());
+ assertEquals(bean1, bean3.getSimpleBean());
+
+ assertUninstall("Name2");
+
+ context1 = assertContext("Name1");
+ bean1 = (SimpleBean) context1.getTarget();
+ assertNotNull(bean1);
+ assertEquals("String1", bean1.getString());
+
+ context3 = assertContext("Name3");
+ bean3 = (SimpleBeanWithDependency) context3.getTarget();
+ assertNotNull(bean3);
+ assertEquals("String3", bean3.getString());
+ assertEquals(bean1, bean3.getSimpleBean());
+
+ context2 = assertInstall(offSetNumber(1), "Name2");
+
+ bean1 = (SimpleBean) context1.getTarget();
+ assertNotNull(bean1);
+ assertEquals("String1", bean1.getString());
+
+ bean2 = (SimpleBeanWithDependency) context2.getTarget();
+ assertNotNull(bean2);
+ assertEquals("String2", bean2.getString());
+ assertEquals(bean1, bean2.getSimpleBean());
+
+ bean3 = (SimpleBeanWithDependency) context3.getTarget();
+ assertNotNull(bean3);
+ assertEquals("String3", bean3.getString());
+ assertEquals(bean1, bean3.getSimpleBean());
+
+ assertUninstall("Name2");
+ context1 = assertContext("Name1");
+ bean1 = (SimpleBean) context1.getTarget();
+ assertNotNull(bean1);
+ assertEquals("String1", bean1.getString());
+
+ context3 = assertContext("Name3");
+ bean3 = (SimpleBeanWithDependency) context3.getTarget();
+ assertNotNull(bean3);
+ assertEquals("String3", bean3.getString());
+ assertEquals(bean1, bean3.getSimpleBean());
+
+ assertUninstall("Name3");
+ context1 = assertContext("Name1", ControllerState.DESCRIBED);
+ assertNull(context1.getTarget());
+
+ context2 = assertInstall(offSetNumber(1), "Name2");
+
+ bean1 = (SimpleBean) context1.getTarget();
+ assertNotNull(bean1);
+ assertEquals("String1", bean1.getString());
+
+ bean2 = (SimpleBeanWithDependency) context2.getTarget();
+ assertNotNull(bean2);
+ assertEquals("String2", bean2.getString());
+ assertEquals(bean1, bean2.getSimpleBean());
+
+ context3 = assertInstall(offSetNumber(2), "Name3");
+ bean3 = (SimpleBeanWithDependency) context3.getTarget();
+ assertNotNull(bean3);
+ assertEquals("String3", bean3.getString());
+ assertEquals(bean1, bean3.getSimpleBean());
+ }
+
+ public void onDemandDependencyReinstall() throws Throwable
+ {
+ buildMetaData();
+ }
+
+ protected void buildMetaData()
+ {
+ AbstractBeanMetaData metaData1 = new AbstractBeanMetaData("Name1", SimpleBeanImpl.class.getName());
+ metaData1.setMode(ControllerMode.ON_DEMAND);
+ HashSet<PropertyMetaData> attributes1 = new HashSet<PropertyMetaData>();
+ attributes1.add(new AbstractPropertyMetaData("string", "String1"));
+ metaData1.setProperties(attributes1);
+
+ AbstractBeanMetaData metaData2 = new AbstractBeanMetaData("Name2", SimpleBeanWithDependencyImpl.class.getName());
+ HashSet<PropertyMetaData> attributes2 = new HashSet<PropertyMetaData>();
+ attributes2.add(new AbstractPropertyMetaData("string", "String2"));
+ attributes2.add(new AbstractPropertyMetaData("simpleBean", new AbstractDependencyValueMetaData("Name1")));
+ metaData2.setProperties(attributes2);
+ addAnnotation(metaData2);
+
+ AbstractBeanMetaData metaData3 = new AbstractBeanMetaData("Name3", SimpleBeanWithDependencyImpl.class.getName());
+ HashSet<PropertyMetaData> attributes3 = new HashSet<PropertyMetaData>();
+ attributes3.add(new AbstractPropertyMetaData("string", "String3"));
+ attributes3.add(new AbstractPropertyMetaData("simpleBean", new AbstractDependencyValueMetaData("Name1")));
+ metaData3.setProperties(attributes3);
+ addAnnotation(metaData3);
+
+ setBeanMetaDatas(new BeanMetaData[] { metaData1, metaData2, metaData3});
+ }
+
+ protected void addAnnotation(AbstractBeanMetaData bmd)
+ {
+ }
+
+ protected int offSetNumber(int i)
+ {
+ return i;
+ }
+
+ protected void assertControllers(ControllerContext...contexts)
+ {
+ if (contexts.length <= 1)
+ return;
+
+ for (int i = 1 ; i < contexts.length ; i++)
+ {
+ if (i > 1)
+ assertSame(contexts[i].getController(), contexts[i-1].getController());
+ }
+ }
+}
\ No newline at end of file
Deleted: projects/kernel/branches/resolver/kernel/src/test/java/org/jboss/test/kernel/dependency/test/OnDemandDependencyXMLTestCase.java
===================================================================
--- projects/kernel/trunk/kernel/src/test/java/org/jboss/test/kernel/dependency/test/OnDemandDependencyXMLTestCase.java 2010-01-15 10:05:32 UTC (rev 99451)
+++ projects/kernel/branches/resolver/kernel/src/test/java/org/jboss/test/kernel/dependency/test/OnDemandDependencyXMLTestCase.java 2010-01-15 12:19:28 UTC (rev 99462)
@@ -1,43 +0,0 @@
-/*
-* JBoss, Home of Professional Open Source
-* Copyright 2005, JBoss Inc., and individual contributors as indicated
-* by the @authors tag. See the copyright.txt in the distribution for a
-* full listing of individual contributors.
-*
-* This is free software; you can redistribute it and/or modify it
-* under the terms of the GNU Lesser General Public License as
-* published by the Free Software Foundation; either version 2.1 of
-* the License, or (at your option) any later version.
-*
-* This software is distributed in the hope that it will be useful,
-* but WITHOUT ANY WARRANTY; without even the implied warranty of
-* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-* Lesser General Public License for more details.
-*
-* You should have received a copy of the GNU Lesser General Public
-* License along with this software; if not, write to the Free
-* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
-* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
-*/
-package org.jboss.test.kernel.dependency.test;
-
-import junit.framework.Test;
-
-/**
- * OnDemand Dependency Test Case.
- *
- * @author <a href="adrian at jboss.com">Adrian Brock</a>
- * @version $Revision$
- */
-public class OnDemandDependencyXMLTestCase extends OnDemandDependencyTestCase
-{
- public static Test suite()
- {
- return suite(OnDemandDependencyXMLTestCase.class);
- }
-
- public OnDemandDependencyXMLTestCase(String name) throws Throwable
- {
- super(name, true);
- }
-}
\ No newline at end of file
Copied: projects/kernel/branches/resolver/kernel/src/test/java/org/jboss/test/kernel/dependency/test/OnDemandDependencyXMLTestCase.java (from rev 99452, projects/kernel/trunk/kernel/src/test/java/org/jboss/test/kernel/dependency/test/OnDemandDependencyXMLTestCase.java)
===================================================================
--- projects/kernel/branches/resolver/kernel/src/test/java/org/jboss/test/kernel/dependency/test/OnDemandDependencyXMLTestCase.java (rev 0)
+++ projects/kernel/branches/resolver/kernel/src/test/java/org/jboss/test/kernel/dependency/test/OnDemandDependencyXMLTestCase.java 2010-01-15 12:19:28 UTC (rev 99462)
@@ -0,0 +1,43 @@
+/*
+* JBoss, Home of Professional Open Source
+* Copyright 2005, JBoss Inc., and individual contributors as indicated
+* by the @authors tag. See the copyright.txt in the distribution for a
+* full listing of individual contributors.
+*
+* This is free software; you can redistribute it and/or modify it
+* under the terms of the GNU Lesser General Public License as
+* published by the Free Software Foundation; either version 2.1 of
+* the License, or (at your option) any later version.
+*
+* This software is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+* Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public
+* License along with this software; if not, write to the Free
+* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+*/
+package org.jboss.test.kernel.dependency.test;
+
+import junit.framework.Test;
+
+/**
+ * OnDemand Dependency Test Case.
+ *
+ * @author <a href="adrian at jboss.com">Adrian Brock</a>
+ * @version $Revision$
+ */
+public class OnDemandDependencyXMLTestCase extends OnDemandDependencyTestCase
+{
+ public static Test suite()
+ {
+ return suite(OnDemandDependencyXMLTestCase.class);
+ }
+
+ public OnDemandDependencyXMLTestCase(String name) throws Throwable
+ {
+ super(name, true, false);
+ }
+}
\ No newline at end of file
Copied: projects/kernel/branches/resolver/kernel/src/test/java/org/jboss/test/kernel/dependency/test/ScopedOnDemandDependencyTestCase.java (from rev 99452, projects/kernel/trunk/kernel/src/test/java/org/jboss/test/kernel/dependency/test/ScopedOnDemandDependencyTestCase.java)
===================================================================
--- projects/kernel/branches/resolver/kernel/src/test/java/org/jboss/test/kernel/dependency/test/ScopedOnDemandDependencyTestCase.java (rev 0)
+++ projects/kernel/branches/resolver/kernel/src/test/java/org/jboss/test/kernel/dependency/test/ScopedOnDemandDependencyTestCase.java 2010-01-15 12:19:28 UTC (rev 99462)
@@ -0,0 +1,76 @@
+/*
+* 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.test.kernel.dependency.test;
+
+import java.util.HashSet;
+import java.util.Set;
+
+import junit.framework.Test;
+
+import org.jboss.beans.metadata.plugins.AbstractAnnotationMetaData;
+import org.jboss.beans.metadata.plugins.AbstractBeanMetaData;
+import org.jboss.beans.metadata.spi.AnnotationMetaData;
+import org.jboss.dependency.spi.ControllerContext;
+import org.jboss.metadata.plugins.scope.DeploymentScope;
+
+/**
+ *
+ * @author <a href="kabir.khan at jboss.com">Kabir Khan</a>
+ * @version $Revision: 1.1 $
+ */
+public class ScopedOnDemandDependencyTestCase extends OnDemandDependencyTestCase
+{
+ public static Test suite()
+ {
+ return suite(ScopedOnDemandDependencyTestCase.class);
+ }
+
+ public ScopedOnDemandDependencyTestCase(String name) throws Throwable
+ {
+ super(name, false, true);
+ }
+
+ public ScopedOnDemandDependencyTestCase(String name, boolean xmltest) throws Throwable
+ {
+ super(name, xmltest, true);
+ }
+
+ protected void addAnnotation(AbstractBeanMetaData bmd)
+ {
+ Set<AnnotationMetaData> annotations = new HashSet<AnnotationMetaData>();
+ annotations.add(new AbstractAnnotationMetaData("@" + DeploymentScope.class.getName() + "(\"somedeployment\")"));
+ bmd.setAnnotations(annotations);
+ }
+
+ protected void assertControllers(ControllerContext...contexts)
+ {
+ if (contexts.length <= 1)
+ return;
+
+ for (int i = 1 ; i < contexts.length ; i++)
+ {
+ assertNotSame(contexts[0].getController(), contexts[i].getController());
+ if (i > 1)
+ assertSame(contexts[i].getController(), contexts[i-1].getController());
+ }
+ }
+}
Copied: projects/kernel/branches/resolver/kernel/src/test/java/org/jboss/test/kernel/dependency/test/ScopedOnDemandDependencyXMLTestCase.java (from rev 99452, projects/kernel/trunk/kernel/src/test/java/org/jboss/test/kernel/dependency/test/ScopedOnDemandDependencyXMLTestCase.java)
===================================================================
--- projects/kernel/branches/resolver/kernel/src/test/java/org/jboss/test/kernel/dependency/test/ScopedOnDemandDependencyXMLTestCase.java (rev 0)
+++ projects/kernel/branches/resolver/kernel/src/test/java/org/jboss/test/kernel/dependency/test/ScopedOnDemandDependencyXMLTestCase.java 2010-01-15 12:19:28 UTC (rev 99462)
@@ -0,0 +1,52 @@
+/*
+* 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.test.kernel.dependency.test;
+
+import junit.framework.Test;
+
+/**
+ *
+ * @author <a href="kabir.khan at jboss.com">Kabir Khan</a>
+ * @version $Revision: 1.1 $
+ */
+public class ScopedOnDemandDependencyXMLTestCase extends ScopedOnDemandDependencyTestCase
+{
+ public static Test suite()
+ {
+ return suite(ScopedOnDemandDependencyXMLTestCase.class);
+ }
+
+ public ScopedOnDemandDependencyXMLTestCase(String name) throws Throwable
+ {
+ super(name, true);
+ }
+
+ @Override
+ protected void buildMetaData()
+ {
+ }
+
+ protected int offSetNumber(int i)
+ {
+ return i + 10;
+ }
+}
Copied: projects/kernel/branches/resolver/kernel/src/test/resources/xml-test/org/jboss/test/kernel/dependency/test/testOnDemandDependencyOnDemandFirst10.xml (from rev 99452, projects/kernel/trunk/kernel/src/test/resources/xml-test/org/jboss/test/kernel/dependency/test/testOnDemandDependencyOnDemandFirst10.xml)
===================================================================
--- projects/kernel/branches/resolver/kernel/src/test/resources/xml-test/org/jboss/test/kernel/dependency/test/testOnDemandDependencyOnDemandFirst10.xml (rev 0)
+++ projects/kernel/branches/resolver/kernel/src/test/resources/xml-test/org/jboss/test/kernel/dependency/test/testOnDemandDependencyOnDemandFirst10.xml 2010-01-15 12:19:28 UTC (rev 99462)
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<deployment xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="urn:jboss:bean-deployer bean-deployer_1_0.xsd"
+ xmlns="urn:jboss:bean-deployer">
+ <bean name="Name1" class="org.jboss.test.kernel.dependency.support.SimpleBeanImpl" mode="On Demand">
+ <property name="string">String1</property>
+ </bean>
+</deployment>
Copied: projects/kernel/branches/resolver/kernel/src/test/resources/xml-test/org/jboss/test/kernel/dependency/test/testOnDemandDependencyOnDemandFirst11.xml (from rev 99452, projects/kernel/trunk/kernel/src/test/resources/xml-test/org/jboss/test/kernel/dependency/test/testOnDemandDependencyOnDemandFirst11.xml)
===================================================================
--- projects/kernel/branches/resolver/kernel/src/test/resources/xml-test/org/jboss/test/kernel/dependency/test/testOnDemandDependencyOnDemandFirst11.xml (rev 0)
+++ projects/kernel/branches/resolver/kernel/src/test/resources/xml-test/org/jboss/test/kernel/dependency/test/testOnDemandDependencyOnDemandFirst11.xml 2010-01-15 12:19:28 UTC (rev 99462)
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<deployment xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="urn:jboss:bean-deployer bean-deployer_1_0.xsd"
+ xmlns="urn:jboss:bean-deployer">
+ <bean name="Name2" class="org.jboss.test.kernel.dependency.support.SimpleBeanWithDependencyImpl">
+ <annotation>@org.jboss.metadata.plugins.scope.DeploymentScope("somedeployment")</annotation>
+ <property name="string">String2</property>
+ <property name="simpleBean"><inject bean="Name1"/></property>
+ </bean>
+</deployment>
Copied: projects/kernel/branches/resolver/kernel/src/test/resources/xml-test/org/jboss/test/kernel/dependency/test/testOnDemandDependencyOnDemandSecond10.xml (from rev 99452, projects/kernel/trunk/kernel/src/test/resources/xml-test/org/jboss/test/kernel/dependency/test/testOnDemandDependencyOnDemandSecond10.xml)
===================================================================
--- projects/kernel/branches/resolver/kernel/src/test/resources/xml-test/org/jboss/test/kernel/dependency/test/testOnDemandDependencyOnDemandSecond10.xml (rev 0)
+++ projects/kernel/branches/resolver/kernel/src/test/resources/xml-test/org/jboss/test/kernel/dependency/test/testOnDemandDependencyOnDemandSecond10.xml 2010-01-15 12:19:28 UTC (rev 99462)
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<deployment xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="urn:jboss:bean-deployer bean-deployer_1_0.xsd"
+ xmlns="urn:jboss:bean-deployer">
+ <bean name="Name1" class="org.jboss.test.kernel.dependency.support.SimpleBeanImpl" mode="On Demand">
+ <property name="string">String1</property>
+ </bean>
+</deployment>
Copied: projects/kernel/branches/resolver/kernel/src/test/resources/xml-test/org/jboss/test/kernel/dependency/test/testOnDemandDependencyOnDemandSecond11.xml (from rev 99452, projects/kernel/trunk/kernel/src/test/resources/xml-test/org/jboss/test/kernel/dependency/test/testOnDemandDependencyOnDemandSecond11.xml)
===================================================================
--- projects/kernel/branches/resolver/kernel/src/test/resources/xml-test/org/jboss/test/kernel/dependency/test/testOnDemandDependencyOnDemandSecond11.xml (rev 0)
+++ projects/kernel/branches/resolver/kernel/src/test/resources/xml-test/org/jboss/test/kernel/dependency/test/testOnDemandDependencyOnDemandSecond11.xml 2010-01-15 12:19:28 UTC (rev 99462)
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<deployment xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="urn:jboss:bean-deployer bean-deployer_1_0.xsd"
+ xmlns="urn:jboss:bean-deployer">
+ <bean name="Name2" class="org.jboss.test.kernel.dependency.support.SimpleBeanWithDependencyImpl">
+ <annotation>@org.jboss.metadata.plugins.scope.DeploymentScope("somedeployment")</annotation>
+ <property name="string">String2</property>
+ <property name="simpleBean"><inject bean="Name1"/></property>
+ </bean>
+</deployment>
Copied: projects/kernel/branches/resolver/kernel/src/test/resources/xml-test/org/jboss/test/kernel/dependency/test/testOnDemandDependencyReinstall10.xml (from rev 99452, projects/kernel/trunk/kernel/src/test/resources/xml-test/org/jboss/test/kernel/dependency/test/testOnDemandDependencyReinstall10.xml)
===================================================================
--- projects/kernel/branches/resolver/kernel/src/test/resources/xml-test/org/jboss/test/kernel/dependency/test/testOnDemandDependencyReinstall10.xml (rev 0)
+++ projects/kernel/branches/resolver/kernel/src/test/resources/xml-test/org/jboss/test/kernel/dependency/test/testOnDemandDependencyReinstall10.xml 2010-01-15 12:19:28 UTC (rev 99462)
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<deployment xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="urn:jboss:bean-deployer bean-deployer_1_0.xsd"
+ xmlns="urn:jboss:bean-deployer">
+ <bean name="Name1" class="org.jboss.test.kernel.dependency.support.SimpleBeanImpl" mode="On Demand">
+ <property name="string">String1</property>
+ </bean>
+</deployment>
Copied: projects/kernel/branches/resolver/kernel/src/test/resources/xml-test/org/jboss/test/kernel/dependency/test/testOnDemandDependencyReinstall11.xml (from rev 99452, projects/kernel/trunk/kernel/src/test/resources/xml-test/org/jboss/test/kernel/dependency/test/testOnDemandDependencyReinstall11.xml)
===================================================================
--- projects/kernel/branches/resolver/kernel/src/test/resources/xml-test/org/jboss/test/kernel/dependency/test/testOnDemandDependencyReinstall11.xml (rev 0)
+++ projects/kernel/branches/resolver/kernel/src/test/resources/xml-test/org/jboss/test/kernel/dependency/test/testOnDemandDependencyReinstall11.xml 2010-01-15 12:19:28 UTC (rev 99462)
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<deployment xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="urn:jboss:bean-deployer bean-deployer_1_0.xsd"
+ xmlns="urn:jboss:bean-deployer">
+ <bean name="Name2" class="org.jboss.test.kernel.dependency.support.SimpleBeanWithDependencyImpl">
+ <annotation>@org.jboss.metadata.plugins.scope.DeploymentScope("somedeployment")</annotation>
+ <property name="string">String2</property>
+ <property name="simpleBean"><inject bean="Name1"/></property>
+ </bean>
+</deployment>
Copied: projects/kernel/branches/resolver/kernel/src/test/resources/xml-test/org/jboss/test/kernel/dependency/test/testOnDemandDependencyReinstall12.xml (from rev 99452, projects/kernel/trunk/kernel/src/test/resources/xml-test/org/jboss/test/kernel/dependency/test/testOnDemandDependencyReinstall12.xml)
===================================================================
--- projects/kernel/branches/resolver/kernel/src/test/resources/xml-test/org/jboss/test/kernel/dependency/test/testOnDemandDependencyReinstall12.xml (rev 0)
+++ projects/kernel/branches/resolver/kernel/src/test/resources/xml-test/org/jboss/test/kernel/dependency/test/testOnDemandDependencyReinstall12.xml 2010-01-15 12:19:28 UTC (rev 99462)
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<deployment xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="urn:jboss:bean-deployer bean-deployer_1_0.xsd"
+ xmlns="urn:jboss:bean-deployer">
+ <bean name="Name3" class="org.jboss.test.kernel.dependency.support.SimpleBeanWithDependencyImpl">
+ <annotation>@org.jboss.metadata.plugins.scope.DeploymentScope("somedeployment")</annotation>
+ <property name="string">String3</property>
+ <property name="simpleBean"><inject bean="Name1"/></property>
+ </bean>
+</deployment>
More information about the jboss-cvs-commits
mailing list