/* */ package org.jboss.dependency.plugins;
/* */
/* */ import java.util.Collection;
/* */ import java.util.Collections;
/* */ import java.util.HashMap;
/* */ import java.util.HashSet;
/* */ import java.util.Iterator;
/* */ import java.util.LinkedHashSet;
/* */ import java.util.List;
/* */ import java.util.Map;
/* */ import java.util.Set;
/* */ import java.util.concurrent.ConcurrentHashMap;
/* */ import java.util.concurrent.CopyOnWriteArrayList;
/* */ import java.util.concurrent.CopyOnWriteArraySet;
/* */ import java.util.concurrent.locks.ReentrantReadWriteLock;
/* */ import java.util.concurrent.locks.ReentrantReadWriteLock.ReadLock;
/* */ import java.util.concurrent.locks.ReentrantReadWriteLock.WriteLock;
/* */ import org.jboss.dependency.plugins.action.SimpleControllerContextAction;
/* */ 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.DependencyInfo;
/* */ import org.jboss.dependency.spi.DependencyItem;
/* */ import org.jboss.dependency.spi.LifecycleCallbackItem;
/* */ import org.jboss.logging.Logger;
/* */ import org.jboss.util.JBossObject;
/* */ import org.jboss.util.JBossStringBuilder;
/* */
/* */ public class AbstractController extends JBossObject
/* */ implements Controller
/* */ {
/* 60 */ private ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
/* */
/* 63 */ private boolean shutdown = false;
/* */
/* 66 */ private List<ControllerState> states = new CopyOnWriteArrayList();
/* */
/* 69 */ private Map<Object, ControllerContext> allContexts = new ConcurrentHashMap();
/* */
/* 72 */ private Map<ControllerState, Set<ControllerContext>> contextsByState = new ConcurrentHashMap();
/* */
/* 75 */ private Map<Object, ControllerContext> errorContexts = new ConcurrentHashMap();
/* */
/* 78 */ private Set<ControllerContext> installing = new CopyOnWriteArraySet();
/* */ private AbstractController parentController;
/* 84 */ private Set<AbstractController> childControllers = new CopyOnWriteArraySet();
/* */
/* 87 */ private Map<Object, Set<CallbackItem<?>>> installCallbacks = new ConcurrentHashMap();
/* 88 */ private Map<Object, Set<CallbackItem<?>>> uninstallCallbacks = new ConcurrentHashMap();
/* */
/* 91 */ private boolean onDemandEnabled = true;
/* */
/* */ public AbstractController()
/* */ {
/* 98 */ addState(ControllerState.NOT_INSTALLED, null);
/* 99 */ addState(ControllerState.PRE_INSTALL, null);
/* 100 */ addState(ControllerState.DESCRIBED, null);
/* 101 */ addState(ControllerState.INSTANTIATED, null);
/* 102 */ addState(ControllerState.CONFIGURED, null);
/* 103 */ addState(ControllerState.CREATE, null);
/* 104 */ addState(ControllerState.START, null);
/* 105 */ addState(ControllerState.INSTALLED, null);
/* */ }
/* */
/* */ public boolean isShutdown()
/* */ {
/* 110 */ lockWrite();
/* */ try
/* */ {
/* 113 */ boolean bool = this.shutdown;
/* */ return bool; } finally { unlockWrite(); } throw localObject;
/* */ }
/* */
/* */ public void checkShutdown()
/* */ {
/* 128 */ lockWrite();
/* */ try
/* */ {
/* 131 */ if (this.shutdown)
/* 132 */ throw new IllegalStateException("Already shutdown");
/* */ }
/* */ finally
/* */ {
/* 136 */ unlockWrite();
/* */ }
/* */ }
/* */
/* */ public void shutdown()
/* */ {
/* 142 */ lockWrite();
/* */ try
/* */ {
/* 145 */ Set children = getControllers();
/* 146 */ if ((children != null) && (!children.isEmpty()))
/* */ {
/* 148 */ for (AbstractController child : children)
/* */ {
/* */ try
/* */ {
/* 152 */ child.shutdown();
/* */ }
/* */ catch (Throwable t)
/* */ {
/* 156 */ this.log.warn("Error during shutdown of child: " + child, t);
/* */ }
/* */ }
/* */ }
/* */
/* 161 */ Set contexts = getAllContexts();
/* 162 */ if ((contexts != null) && (!contexts.isEmpty()))
/* */ {
/* 164 */ for (ControllerContext context : contexts)
/* */ {
/* */ try
/* */ {
/* 168 */ uninstall(context.getName());
/* */ }
/* */ catch (Throwable t)
/* */ {
/* 172 */ this.log.warn("Error during shutdown while uninstalling: " + context, t);
/* */ }
/* */ }
/* */ }
/* */ }
/* */ finally
/* */ {
/* 179 */ this.shutdown = true;
/* 180 */ unlockWrite();
/* */ }
/* */ }
/* */
/* */ public void addState(ControllerState state, ControllerState before)
/* */ {
/* 187 */ lockWrite();
/* */ try
/* */ {
/* 190 */ if (this.states.contains(state))
/* */ return;
/* 193 */ if (before == null)
/* */ {
/* 195 */ this.states.add(state);
/* */ }
/* */ else
/* */ {
/* 199 */ int index = this.states.indexOf(before);
/* 200 */ if (index == -1)
/* 201 */ throw new IllegalStateException(before + " is not a state in the controller.");
/* 202 */ this.states.add(index, state);
/* */ }
/* */
/* 205 */ Set contexts = new CopyOnWriteArraySet();
/* 206 */ this.contextsByState.put(state, contexts);
/* */ }
/* */ finally
/* */ {
/* 210 */ unlockWrite();
/* */ }
/* */ }
/* */
/* */ void addControllerContext(ControllerContext context)
/* */ {
/* 216 */ lockWrite();
/* */ try
/* */ {
/* 219 */ registerControllerContext(context);
/* */ }
/* */ finally
/* */ {
/* 223 */ unlockWrite();
/* */ }
/* */ }
/* */
/* */ void removeControllerContext(ControllerContext context)
/* */ {
/* 229 */ lockWrite();
/* */ try
/* */ {
/* 232 */ unregisterControllerContext(context);
/* */ }
/* */ finally
/* */ {
/* 236 */ unlockWrite();
/* */ }
/* */ }
/* */
/* */ protected AbstractController getParentController()
/* */ {
/* 242 */ return this.parentController;
/* */ }
/* */
/* */ protected void setParentController(AbstractController parentController)
/* */ {
/* 247 */ this.parentController = parentController;
/* */ }
/* */
/* */ public Set<AbstractController> getControllers()
/* */ {
/* 252 */ lockRead();
/* */ try
/* */ {
/* 255 */ Set localSet = Collections.unmodifiableSet(this.childControllers);
/* */ return localSet; } finally { unlockRead(); } throw localObject;
/* */ }
/* */
/* */ public boolean addController(AbstractController controller)
/* */ {
/* 265 */ lockWrite();
/* */ try
/* */ {
/* 268 */ boolean bool = this.childControllers.add(controller);
/* */ return bool; } finally { unlockWrite(); } throw localObject;
/* */ }
/* */
/* */ public boolean removeController(AbstractController controller)
/* */ {
/* 278 */ lockWrite();
/* */ try
/* */ {
/* 281 */ boolean bool = this.childControllers.remove(controller);
/* */ return bool; } finally { unlockWrite(); } throw localObject;
/* */ }
/* */
/* */ public boolean isActive()
/* */ {
/* 296 */ lockRead();
/* */ try
/* */ {
/* 299 */ int i = !this.allContexts.isEmpty() ? 1 : 0;
/* */ return i; } finally { unlockRead(); } throw localObject;
/* */ }
/* */
/* */ public Set<ControllerContext> getAllContexts()
/* */ {
/* 309 */ lockRead();
/* */ try
/* */ {
/* 312 */ LinkedHashSet result = new LinkedHashSet();
/* 313 */ for (int i = this.states.size() - 1; i >= 0; i--)
/* */ {
/* 315 */ ControllerState state = (ControllerState)this.states.get(i);
/* 316 */ result.addAll((Collection)this.contextsByState.get(state));
/* */ }
/* 318 */ result.addAll(this.errorContexts.values());
/* 319 */ i = result;
/* */ return i; } finally { unlockRead(); } throw localObject;
/* */ }
/* */
/* */ public ControllerContext getContext(Object name, ControllerState state)
/* */ {
/* 329 */ if (name == null) {
/* 330 */ throw new IllegalArgumentException("Null name");
/* */ }
/* 332 */ lockRead();
/* */ try
/* */ {
/* 335 */ ControllerContext result = getRegisteredControllerContext(name, false);
/* 336 */ if ((result != null) && (state != null))
/* */ {
/* 338 */ required = this.states.indexOf(state);
/* 339 */ if (required == -1)
/* 340 */ throw new IllegalArgumentException("Unknown state " + state + " states=" + this.states);
/* 341 */ int current = this.states.indexOf(result.getState());
/* 342 */ if (current < required) {
/* 343 */ Object localObject1 = null;
/* */ return localObject1;
/* */ }
/* */ }
/* 345 */ int required = result;
/* */ return required; } finally { unlockRead(); } throw localObject2;
/* */ }
/* */
/* */ public ControllerContext getInstalledContext(Object name)
/* */ {
/* 355 */ return getContext(name, ControllerState.INSTALLED);
/* */ }
/* */
/* */ public Set<ControllerContext> getNotInstalled()
/* */ {
/* 360 */ lockWrite();
/* */ try
/* */ {
/* 363 */ Set result = new HashSet(this.errorContexts.values());
/* 364 */ for (int i = 0; !ControllerState.INSTALLED.equals(this.states.get(i)); i++)
/* */ {
/* 366 */ Set stateContexts = getContextsByState((ControllerState)this.states.get(i));
/* 367 */ result.addAll(stateContexts);
/* */ }
/* 369 */ i = result;
/* */ return i; } finally { unlockWrite(); } throw localObject;
/* */ }
/* */
/* */ public List<ControllerState> getStates()
/* */ {
/* 379 */ return this.states;
/* */ }
/* */
/* */ public Set<ControllerContext> getContextsByState(ControllerState state)
/* */ {
/* 384 */ return (Set)this.contextsByState.get(state);
/* */ }
/* */
/* */ public void install(ControllerContext context) throws Throwable
/* */ {
/* 389 */ boolean trace = this.log.isTraceEnabled();
/* */
/* 391 */ if (context == null) {
/* 392 */ throw new IllegalArgumentException("Null context");
/* */ }
/* 394 */ Object name = context.getName();
/* 395 */ if (name == null) {
/* 396 */ throw new IllegalArgumentException("Null name " + context.toShortString());
/* */ }
/* 398 */ install(context, trace);
/* */ }
/* */
/* */ public void change(ControllerContext context, ControllerState state) throws Throwable
/* */ {
/* 403 */ boolean trace = this.log.isTraceEnabled();
/* */
/* 405 */ if (context == null) {
/* 406 */ throw new IllegalArgumentException("Null context");
/* */ }
/* 408 */ if (state == null) {
/* 409 */ throw new IllegalArgumentException("Null state");
/* */ }
/* 411 */ change(context, state, trace);
/* */ }
/* */
/* */ public void enableOnDemand(ControllerContext context) throws Throwable
/* */ {
/* 416 */ boolean trace = this.log.isTraceEnabled();
/* */
/* 418 */ if (context == null) {
/* 419 */ throw new IllegalArgumentException("Null context");
/* */ }
/* 421 */ enableOnDemand(context, trace);
/* */ }
/* */
/* */ public ControllerContext uninstall(Object name)
/* */ {
/* 426 */ return uninstall(name, 0);
/* */ }
/* */
/* */ public void addAlias(Object alias, Object original) throws Throwable
/* */ {
/* 431 */ Map map = new HashMap();
/* 432 */ map.put(ControllerState.INSTALLED, new AliasControllerContextAction(null));
/* 433 */ ControllerContextActions actions = new AbstractControllerContextActions(map);
/* 434 */ install(new AliasControllerContext(alias, original, actions));
/* */ }
/* */
/* */ public void removeAlias(Object alias)
/* */ {
/* 439 */ uninstall(alias + "_Alias");
/* */ }
/* */
/* */ protected ControllerContext uninstall(Object name, int level)
/* */ {
/* 446 */ boolean trace = this.log.isTraceEnabled();
/* */
/* 448 */ if (name == null) {
/* 449 */ throw new IllegalArgumentException("Null name");
/* */ }
/* 451 */ lockWrite();
/* */ try
/* */ {
/* 454 */ if ((this.errorContexts.remove(name) != null) && (trace)) {
/* 455 */ this.log.trace("Tidied up context in error state: " + name);
/* */ }
/* 457 */ ControllerContext context = getRegisteredControllerContext(name, false);
/* 458 */ if (context != null)
/* */ {
/* 460 */ if (trace) {
/* 461 */ this.log.trace("Uninstalling " + context.toShortString());
/* */ }
/* 463 */ uninstallContext(context, ControllerState.NOT_INSTALLED, trace);
/* */ try
/* */ {
/* 467 */ unregisterControllerContext(context);
/* */ }
/* */ catch (Throwable t)
/* */ {
/* 471 */ this.log.warn("Error unregistering context: " + context.toShortString() + " with name: " + name);
/* */ }
/* */
/* 474 */ AbstractController parent = getParentController();
/* 475 */ while (parent != null)
/* */ {
/* */ try
/* */ {
/* 479 */ parent.unregisterControllerContext(context);
/* */ }
/* */ catch (Throwable t)
/* */ {
/* 483 */ this.log.warn("Error unregistering context in parent controller: " + context.toShortString() + " with name: " + name);
/* */ }
/* 485 */ parent = parent.getParentController();
/* */ }
/* */ }
/* */ else
/* */ {
/* 490 */ for (AbstractController controller : getControllers())
/* */ {
/* 492 */ context = controller.uninstall(name, level + 1);
/* 493 */ if (context != null)
/* */ break;
/* */ }
/* */ }
/* 497 */ if ((context == null) && (level == 0))
/* 498 */ throw new IllegalStateException("Not installed: " + name);
/* 499 */ ??? = context;
/* */ return ???; } finally { unlockWrite(); } throw localObject;
/* */ }
/* */
/* */ protected void install(ControllerContext context, boolean trace)
/* */ throws Throwable
/* */ {
/* 516 */ lockWrite();
/* */ try
/* */ {
/* 519 */ checkShutdown();
/* */
/* 521 */ Object name = context.getName();
/* */
/* 524 */ if (getRegisteredControllerContext(name, false) != null) {
/* 525 */ throw new IllegalStateException(name + " is already installed.");
/* */ }
/* */
/* 528 */ Set aliases = context.getAliases();
/* */ Iterator i$;
/* 529 */ if ((aliases != null) && (!aliases.isEmpty()))
/* */ {
/* 531 */ for (i$ = aliases.iterator(); i$.hasNext(); ) { Object alias = i$.next();
/* */
/* 533 */ if (getRegisteredControllerContext(alias, false) != null) {
/* 534 */ throw new IllegalStateException(alias + " an alias of " + name + " is already installed.");
/* */ }
/* */ }
/* */ }
/* 538 */ if (ControllerMode.AUTOMATIC.equals(context.getMode())) {
/* 539 */ context.setRequiredState(ControllerState.INSTALLED);
/* */ }
/* 541 */ if (trace) {
/* 542 */ this.log.trace("Installing " + context.toShortString());
/* */ }
/* 544 */ context.setController(this);
/* 545 */ DependencyInfo dependencies = context.getDependencyInfo();
/* 546 */ if (trace)
/* */ {
/* 548 */ String dependsOn = null;
/* 549 */ if (dependencies != null)
/* */ {
/* 551 */ Set set = dependencies.getIDependOn(null);
/* 552 */ if (set != null)
/* 553 */ dependsOn = set.toString();
/* */ }
/* 555 */ this.log.trace("Dependencies for " + name + ": " + dependsOn);
/* */ }
/* */
/* 558 */ boolean ok = incrementState(context, trace);
/* 559 */ if (ok)
/* */ {
/* */ try
/* */ {
/* 563 */ registerControllerContext(context);
/* */ }
/* */ catch (Throwable t)
/* */ {
/* 568 */ ok = false;
/* 569 */ throw t;
/* */ }
/* */ }
/* 572 */ if (ok)
/* */ {
/* 574 */ resolveContexts(trace);
/* */ }
/* */ else
/* */ {
/* 578 */ this.errorContexts.remove(context);
/* 579 */ throw context.getError();
/* */ }
/* */ }
/* */ finally
/* */ {
/* 584 */ unlockWrite();
/* */ }
/* */ }
/* */
/* */ protected void change(ControllerContext context, ControllerState state, boolean trace)
/* */ throws Throwable
/* */ {
/* 598 */ lockWrite();
/* */ try
/* */ {
/* 601 */ checkShutdown();
/* */
/* 603 */ ControllerState fromState = context.getState();
/* 604 */ int currentIndex = this.states.indexOf(fromState);
/* 605 */ int requiredIndex = this.states.indexOf(state);
/* 606 */ if (requiredIndex == -1) {
/* 607 */ throw new IllegalArgumentException("Unknown state: " + state);
/* */ }
/* 609 */ if (currentIndex == requiredIndex)
/* */ {
/* 611 */ if (trace)
/* 612 */ this.log.trace("No change required toState=" + state.getStateString() + " " + context.toShortString());
/* */ return;
/* */ }
/* 616 */ if (trace) {
/* 617 */ this.log.trace("Change toState=" + state.getStateString() + " " + context.toShortString());
/* */ }
/* 619 */ context.setRequiredState(state);
/* */
/* 621 */ if (currentIndex < requiredIndex) {
/* 622 */ resolveContexts(trace);
/* */ }
/* */ else {
/* 625 */ while (currentIndex > requiredIndex)
/* */ {
/* 627 */ uninstallContext(context, trace);
/* 628 */ currentIndex = this.states.indexOf(context.getState());
/* */ }
/* */ }
/* */ }
/* */ finally
/* */ {
/* 634 */ unlockWrite();
/* */ }
/* */ }
/* */
/* */ protected void enableOnDemand(ControllerContext context, boolean trace)
/* */ throws Throwable
/* */ {
/* 647 */ lockWrite();
/* */ try
/* */ {
/* 650 */ checkShutdown();
/* */
/* 652 */ if (!ControllerMode.ON_DEMAND.equals(context.getMode())) {
/* 653 */ throw new IllegalStateException("Context is not ON DEMAND: " + context.toShortString());
/* */ }
/* */
/* 656 */ getRegisteredControllerContext(context.getName(), true);
/* */
/* 659 */ if (ControllerState.INSTALLED.equals(context.getRequiredState())) return;
/* 661 */ context.setRequiredState(ControllerState.INSTALLED);
/* */
/* 663 */ if (trace) {
/* 664 */ this.log.trace("Enable onDemand: " + context.toShortString());
/* */ }
/* 666 */ this.onDemandEnabled = true;
/* */ }
/* */ finally
/* */ {
/* 670 */ unlockWrite();
/* */ }
/* */ }
/* */
/* */ protected boolean incrementState(ControllerContext context, boolean trace)
/* */ {
/* 685 */ ControllerState fromState = context.getState();
/* */
/* 687 */ Controller fromController = context.getController();
/* 688 */ Set fromContexts = null;
/* */
/* 690 */ int currentIndex = -1;
/* 691 */ if (ControllerState.ERROR.equals(fromState))
/* */ {
/* 693 */ this.errorContexts.remove(context);
/* 694 */ Throwable error = null;
/* 695 */ unlockWrite();
/* */ try
/* */ {
/* 698 */ install(context, ControllerState.ERROR, ControllerState.NOT_INSTALLED);
/* */ }
/* */ catch (Throwable t)
/* */ {
/* 702 */ error = t;
/* */ }
/* */ finally
/* */ {
/* 706 */ lockWrite();
/* 707 */ if (error != null)
/* */ {
/* 709 */ this.log.error("Error during initial installation: " + context.toShortString(), error);
/* 710 */ context.setError(error);
/* 711 */ this.errorContexts.put(context.getName(), context);
/* 712 */ return false;
/* */ }
/* */ }
/* 715 */ Set notInstalled = fromController.getContextsByState(ControllerState.NOT_INSTALLED);
/* 716 */ notInstalled.add(context);
/* 717 */ context.setState(ControllerState.NOT_INSTALLED);
/* */ }
/* */ else
/* */ {
/* 721 */ currentIndex = this.states.indexOf(fromState);
/* 722 */ fromContexts = fromController.getContextsByState(fromState);
/* 723 */ if (!fromContexts.contains(context)) {
/* 724 */ throw new IllegalStateException("Context not found in previous state: " + context.toShortString());
/* */ }
/* */ }
/* 727 */ int toIndex = currentIndex + 1;
/* 728 */ ControllerState toState = (ControllerState)this.states.get(toIndex);
/* */
/* 730 */ unlockWrite();
/* 731 */ Throwable error = null;
/* */ try
/* */ {
/* 734 */ install(context, fromState, toState);
/* */
/* 736 */ if (fromContexts != null)
/* 737 */ fromContexts.remove(context);
/* 738 */ Controller toController = context.getController();
/* 739 */ Set toContexts = toController.getContextsByState(toState);
/* 740 */ toContexts.add(context);
/* 741 */ context.setState(toState);
/* */
/* 743 */ handleInstallLifecycleCallbacks(context, toState);
/* 744 */ resolveCallbacks(context, toState, true);
/* */ }
/* */ catch (Throwable t)
/* */ {
/* 748 */ error = t;
/* */ }
/* */ finally
/* */ {
/* 752 */ lockWrite();
/* 753 */ if (error != null)
/* */ {
/* 755 */ this.log.error("Error installing to " + toState.getStateString() + ": " + context.toShortString(), error);
/* 756 */ uninstallContext(context, ControllerState.NOT_INSTALLED, trace);
/* 757 */ this.errorContexts.put(context.getName(), context);
/* 758 */ context.setError(error);
/* 759 */ return false;
/* */ }
/* */ }
/* */
/* 763 */ return true;
/* */ }
/* */
/* */ protected void resolveContexts(boolean trace)
/* */ {
/* 775 */ boolean resolutions = true;
/* 776 */ while ((resolutions) || (this.onDemandEnabled))
/* */ {
/* 778 */ this.onDemandEnabled = false;
/* 779 */ resolutions = false;
/* 780 */ for (int i = 0; i < this.states.size() - 1; i++)
/* */ {
/* 782 */ ControllerState fromState = (ControllerState)this.states.get(i);
/* 783 */ ControllerState toState = (ControllerState)this.states.get(i + 1);
/* 784 */ if (!resolveContexts(fromState, toState, trace))
/* */ continue;
/* 786 */ resolutions = true;
/* 787 */ break;
/* */ }
/* */
/* */ }
/* */
/* 792 */ if (trace)
/* */ {
/* */ ControllerState nextState;
/* 794 */ for (int i = 0; i < this.states.size() - 1; i++)
/* */ {
/* 796 */ ControllerState state = (ControllerState)this.states.get(i);
/* 797 */ nextState = (ControllerState)this.states.get(i + 1);
/* 798 */ Set stillUnresolved = (Set)this.contextsByState.get(state);
/* 799 */ if (stillUnresolved.isEmpty())
/* */ continue;
/* 801 */ for (ControllerContext ctx : stillUnresolved)
/* */ {
/* 803 */ if (advance(ctx)) {
/* 804 */ this.log.trace("Still unresolved " + nextState.getStateString() + ": " + ctx);
/* */ }
/* */ }
/* */ }
/* */
/* */ }
/* */
/* 811 */ for (AbstractController controller : this.childControllers)
/* */ {
/* 813 */ controller.lockWrite();
/* */ try
/* */ {
/* 816 */ controller.resolveContexts(trace);
/* */ }
/* */ finally
/* */ {
/* 820 */ controller.unlockWrite();
/* */ }
/* */ }
/* */ }
/* */
/* */ protected boolean resolveContexts(ControllerState fromState, ControllerState toState, boolean trace)
/* */ {
/* 837 */ boolean resolutions = false;
/* 838 */ Set unresolved = (Set)this.contextsByState.get(fromState);
/* 839 */ Set resolved = resolveContexts(unresolved, toState, trace);
/* 840 */ if (!resolved.isEmpty())
/* */ {
/* 842 */ for (ControllerContext context : resolved)
/* */ {
/* 844 */ Object name = context.getName();
/* 845 */ if (!fromState.equals(context.getState()))
/* */ {
/* 847 */ if (trace)
/* 848 */ this.log.trace("Skipping already installed " + name + " for " + toState.getStateString());
/* */ }
/* 850 */ else if (!this.installing.add(context))
/* */ {
/* 852 */ if (trace) {
/* 853 */ this.log.trace("Already installing " + name + " for " + toState.getStateString());
/* */ }
/* */ }
/* */ else {
/* */ try
/* */ {
/* 859 */ if (trace) {
/* 860 */ this.log.trace("Dependencies resolved " + name + " for " + toState.getStateString());
/* */ }
/* 862 */ if (incrementState(context, trace))
/* */ {
/* 864 */ resolutions = true;
/* 865 */ if (trace)
/* 866 */ this.log.trace(name + " " + toState.getStateString());
/* */ }
/* */ }
/* */ finally
/* */ {
/* 871 */ this.installing.remove(context);
/* */ }
/* */ }
/* */ }
/* */ }
/* */
/* 877 */ return resolutions;
/* */ }
/* */
/* */ protected Set<ControllerContext> resolveContexts(Set<ControllerContext> contexts, ControllerState state, boolean trace)
/* */ {
/* 892 */ HashSet result = new HashSet();
/* */
/* 894 */ if (!contexts.isEmpty())
/* */ {
/* 896 */ for (ControllerContext ctx : contexts)
/* */ {
/* 898 */ if (advance(ctx))
/* */ {
/* 900 */ DependencyInfo dependencies = ctx.getDependencyInfo();
/* 901 */ if (dependencies.resolveDependencies(this, state)) {
/* 902 */ result.add(ctx);
/* */ }
/* */ }
/* */ }
/* */ }
/* 907 */ return result;
/* */ }
/* */
/* */ protected void uninstallContext(ControllerContext context, ControllerState toState, boolean trace)
/* */ {
/* 921 */ int targetState = this.states.indexOf(toState);
/* 922 */ if (targetState == -1) {
/* 923 */ this.log.error("INTERNAL ERROR: unknown state " + toState + " states=" + this.states, new Exception("STACKTRACE"));
/* */ }
/* */ while (true)
/* */ {
/* 927 */ ControllerState fromState = context.getState();
/* 928 */ if (ControllerState.ERROR.equals(fromState))
/* 929 */ return;
/* 930 */ int currentState = this.states.indexOf(fromState);
/* 931 */ if (currentState == -1)
/* 932 */ this.log.error("INTERNAL ERROR: current state not found: " + context.toShortString(), new Exception("STACKTRACE"));
/* 933 */ if (targetState > currentState) {
/* 934 */ return;
/* */ }
/* 936 */ uninstallContext(context, trace);
/* */ }
/* */ }
/* */
/* */ protected void uninstallContext(ControllerContext context, boolean trace)
/* */ {
/* 950 */ Object name = context.getName();
/* */
/* 952 */ ControllerState fromState = context.getState();
/* 953 */ int currentIndex = this.states.indexOf(fromState);
/* */
/* 955 */ if (trace) {
/* 956 */ this.log.trace("Uninstalling " + name + " from " + fromState.getStateString());
/* */ }
/* 958 */ Controller fromController = context.getController();
/* */
/* 960 */ Set fromContexts = fromController.getContextsByState(fromState);
/* 961 */ if ((fromContexts == null) || (!fromContexts.remove(context))) {
/* 962 */ throw new Error("INTERNAL ERROR: context not found in previous state " + fromState.getStateString() + " context=" + context.toShortString(), new Exception("STACKTRACE"));
/* */ }
/* 964 */ DependencyInfo dependencies = context.getDependencyInfo();
/* 965 */ Set dependsOnMe = dependencies.getDependsOnMe(null);
/* 966 */ if (!dependsOnMe.isEmpty())
/* */ {
/* 968 */ for (DependencyItem item : dependsOnMe)
/* */ {
/* 970 */ if (item.isResolved())
/* */ {
/* 972 */ ControllerState dependentState = item.getDependentState();
/* 973 */ if ((dependentState == null) || (dependentState.equals(fromState)))
/* */ {
/* 975 */ if (item.unresolved(this))
/* */ {
/* 977 */ ControllerContext dependent = getContext(item.getName(), null);
/* 978 */ if (dependent != null)
/* */ {
/* 980 */ ControllerState whenRequired = item.getWhenRequired();
/* 981 */ if (whenRequired == null)
/* 982 */ whenRequired = ControllerState.NOT_INSTALLED;
/* 983 */ int proposed = this.states.indexOf(whenRequired);
/* 984 */ int actual = this.states.indexOf(dependent.getState());
/* 985 */ if (proposed <= actual) {
/* 986 */ uninstallContext(dependent, whenRequired, trace);
/* */ }
/* */ }
/* */ }
/* */ }
/* */ }
/* */ }
/* */ }
/* 994 */ int toIndex = currentIndex - 1;
/* 995 */ if (toIndex == -1)
/* */ {
/* 997 */ context.setError(new IllegalStateException("Cannot uninstall from " + fromState));
/* 998 */ return;
/* */ }
/* */
/* 1001 */ ControllerState toState = (ControllerState)this.states.get(toIndex);
/* */
/* 1003 */ unlockWrite();
/* */ try
/* */ {
/* 1006 */ resolveCallbacks(context, fromState, false);
/* 1007 */ handleUninstallLifecycleCallbacks(context, toState);
/* */
/* 1009 */ uninstall(context, fromState, toState);
/* */
/* 1011 */ Controller toController = context.getController();
/* 1012 */ Set toContexts = toController.getContextsByState(toState);
/* 1013 */ toContexts.add(context);
/* 1014 */ context.setState(toState);
/* */ }
/* */ catch (Throwable t)
/* */ {
/* 1018 */ this.log.warn("Error uninstalling from " + fromState.getStateString() + ": " + context.toShortString(), t);
/* */ }
/* */ finally
/* */ {
/* 1022 */ lockWrite();
/* */ }
/* */ }
/* */
/* */ protected <T> void addCallback(Object name, boolean isInstallPhase, CallbackItem<T> callback)
/* */ {
/* 1036 */ lockWrite();
/* */ try
/* */ {
/* 1039 */ Map map = isInstallPhase ? this.installCallbacks : this.uninstallCallbacks;
/* 1040 */ Set callbacks = (Set)map.get(name);
/* 1041 */ if (callbacks == null)
/* */ {
/* 1043 */ callbacks = new HashSet();
/* 1044 */ map.put(name, callbacks);
/* */ }
/* 1046 */ callbacks.add(callback);
/* */ }
/* */ finally
/* */ {
/* 1050 */ unlockWrite();
/* */ }
/* */ }
/* */
/* */ protected <T> void removeCallback(Object name, boolean isInstallPhase, CallbackItem<T> callback)
/* */ {
/* 1064 */ lockWrite();
/* */ try
/* */ {
/* 1067 */ Map map = isInstallPhase ? this.installCallbacks : this.uninstallCallbacks;
/* 1068 */ Set callbacks = (Set)map.get(name);
/* 1069 */ if (callbacks != null)
/* */ {
/* 1071 */ callbacks.remove(callback);
/* 1072 */ if (callbacks.isEmpty())
/* 1073 */ map.remove(name);
/* */ }
/* */ }
/* */ finally
/* */ {
/* 1078 */ unlockWrite();
/* */ }
/* */ }
/* */
/* */ protected Set<CallbackItem<?>> getDependencyCallbacks(ControllerContext context, boolean isInstallPhase)
/* */ {
/* 1091 */ DependencyInfo di = context.getDependencyInfo();
/* 1092 */ if (di != null)
/* */ {
/* 1094 */ return isInstallPhase ? di.getInstallItems() : di.getUninstallItems();
/* */ }
/* 1096 */ return null;
/* */ }
/* */
/* */ protected Set<CallbackItem<?>> getCallbacks(Object name, boolean isInstallPhase)
/* */ {
/* 1108 */ lockRead();
/* */ try
/* */ {
/* 1111 */ Map map = isInstallPhase ? this.installCallbacks : this.uninstallCallbacks;
/* 1112 */ Set callbacks = (Set)map.get(name);
/* 1113 */ HashSet localHashSet = callbacks != null ? callbacks : new HashSet();
/* */ return localHashSet; } finally { unlockRead(); } throw localObject;
/* */ }
/* */
/* */ protected void resolveCallbacks(Set<CallbackItem<?>> callbacks, ControllerState state, boolean execute, boolean isInstallPhase, boolean type)
/* */ {
/* 1132 */ if ((callbacks != null) && (!callbacks.isEmpty()))
/* */ {
/* 1134 */ for (CallbackItem callback : callbacks)
/* */ {
/* 1136 */ if (callback.getWhenRequired().equals(state))
/* */ {
/* 1138 */ if (isInstallPhase)
/* */ {
/* 1140 */ addCallback(callback.getIDependOn(), type, callback);
/* */ }
/* */ else
/* */ {
/* 1144 */ removeCallback(callback.getIDependOn(), type, callback);
/* */ }
/* 1146 */ if (execute)
/* */ {
/* */ try
/* */ {
/* 1150 */ callback.ownerCallback(this, isInstallPhase);
/* */ }
/* */ catch (Throwable t)
/* */ {
/* 1154 */ this.log.warn("Broken callback: " + callback, t);
/* */ }
/* */ }
/* */ }
/* */ }
/* */ }
/* */ }
/* */
/* */ protected void resolveCallbacks(ControllerContext context, ControllerState state, boolean isInstallPhase)
/* */ {
/* */ try
/* */ {
/* 1174 */ Set installs = getDependencyCallbacks(context, true);
/* 1175 */ resolveCallbacks(installs, state, isInstallPhase, isInstallPhase, true);
/* 1176 */ Set uninstalls = getDependencyCallbacks(context, false);
/* 1177 */ resolveCallbacks(uninstalls, state, !isInstallPhase, isInstallPhase, false);
/* */
/* 1180 */ DependencyInfo dependencyInfo = context.getDependencyInfo();
/* 1181 */ if ((dependencyInfo != null) && (dependencyInfo.isAutowireCandidate()))
/* */ {
/* 1184 */ Set existingCallbacks = getCallbacks(context.getName(), isInstallPhase);
/* */
/* 1186 */ Collection classes = getClassesImplemented(context.getTarget());
/* 1187 */ if ((classes != null) && (!classes.isEmpty()))
/* */ {
/* 1189 */ for (Class clazz : classes)
/* */ {
/* 1191 */ existingCallbacks.addAll(getCallbacks(clazz, isInstallPhase));
/* */ }
/* */
/* */ }
/* */
/* 1196 */ if ((existingCallbacks != null) && (!existingCallbacks.isEmpty()))
/* */ {
/* 1198 */ for (CallbackItem callback : existingCallbacks)
/* */ {
/* 1200 */ if (state.equals(callback.getDependentState()))
/* */ {
/* */ try
/* */ {
/* 1204 */ callback.changeCallback(this, context, isInstallPhase);
/* */ }
/* */ catch (Throwable t)
/* */ {
/* 1208 */ this.log.warn("Broken callback: " + callback, t);
/* */ }
/* */ }
/* */ }
/* */ }
/* */ }
/* */
/* */ }
/* */ catch (Throwable t)
/* */ {
/* 1218 */ this.log.warn("Cannot resolve callbacks.", t);
/* */ }
/* */ }
/* */
/* */ protected void handleInstallLifecycleCallbacks(ControllerContext context, ControllerState state) throws Throwable
/* */ {
/* 1224 */ handleLifecycleCallbacks(context, state, true);
/* */ }
/* */
/* */ protected void handleUninstallLifecycleCallbacks(ControllerContext context, ControllerState state) throws Throwable
/* */ {
/* 1229 */ int index = this.states.indexOf(state);
/* 1230 */ ControllerState oldState = (ControllerState)this.states.get(index + 1);
/* 1231 */ handleLifecycleCallbacks(context, oldState, false);
/* */ }
/* */
/* */ protected void handleLifecycleCallbacks(ControllerContext context, ControllerState state, boolean install) throws Throwable
/* */ {
/* 1236 */ DependencyInfo di = context.getDependencyInfo();
/* 1237 */ List callbacks = di.getLifecycleCallbacks();
/* 1238 */ for (LifecycleCallbackItem callback : callbacks)
/* */ {
/* 1240 */ if (callback.getWhenRequired().equals(state))
/* */ {
/* 1242 */ if (install)
/* 1243 */ callback.install(context);
/* */ else
/* 1245 */ callback.uninstall(context);
/* */ }
/* */ }
/* */ }
/* */
/* */ protected boolean isAutowireCandidate(ControllerContext context)
/* */ {
/* 1258 */ return true;
/* */ }
/* */
/* */ protected Collection<Class<?>> getClassesImplemented(Object target)
/* */ {
/* 1269 */ if (target == null)
/* 1270 */ return null;
/* 1271 */ Set classes = new HashSet();
/* 1272 */ traverseClass(target.getClass(), classes);
/* 1273 */ return classes;
/* */ }
/* */
/* */ protected void traverseClass(Class<?> clazz, Set<Class<?>> classes)
/* */ {
/* 1284 */ if ((clazz != null) && (!Object.class.equals(clazz)))
/* */ {
/* 1286 */ classes.add(clazz);
/* 1287 */ traverseClass(clazz.getSuperclass(), classes);
/* 1288 */ Class[] interfaces = clazz.getInterfaces();
/* */
/* 1290 */ for (Class intface : interfaces)
/* */ {
/* 1292 */ traverseClass(intface, classes);
/* */ }
/* */ }
/* */ }
/* */
/* */ protected void install(ControllerContext context, ControllerState fromState, ControllerState toState)
/* */ throws Throwable
/* */ {
/* 1309 */ context.install(fromState, toState);
/* */ }
/* */
/* */ protected void uninstall(ControllerContext context, ControllerState fromState, ControllerState toState)
/* */ {
/* 1323 */ context.uninstall(fromState, toState);
/* */ }
/* */
/* */ protected boolean advance(ControllerContext context)
/* */ {
/* 1336 */ ControllerMode mode = context.getMode();
/* */
/* 1339 */ if (ControllerMode.DISABLED.equals(mode)) {
/* 1340 */ return false;
/* */ }
/* 1342 */ ControllerState fromState = context.getState();
/* 1343 */ int fromIndex = this.states.indexOf(fromState);
/* 1344 */ ControllerState requiredState = context.getRequiredState();
/* 1345 */ int requiredIndex = this.states.indexOf(requiredState);
/* */
/* 1347 */ return fromIndex < requiredIndex;
/* */ }
/* */
/* */ protected void lockRead()
/* */ {
/* 1355 */ this.lock.readLock().lock();
/* */ }
/* */
/* */ protected void unlockRead()
/* */ {
/* 1363 */ this.lock.readLock().unlock();
/* */ }
/* */
/* */ protected void lockWrite()
/* */ {
/* 1371 */ this.lock.writeLock().lock();
/* */ }
/* */
/* */ protected void unlockWrite()
/* */ {
/* 1379 */ this.lock.writeLock().unlock();
/* */ }
/* */
/* */ protected ControllerContext getRegisteredControllerContext(Object name, boolean mustExist)
/* */ {
/* 1395 */ if (name == null) {
/* 1396 */ throw new IllegalArgumentException("Null name");
/* */ }
/* 1398 */ ControllerContext result = (ControllerContext)this.allContexts.get(name);
/* 1399 */ if ((mustExist) && (result == null))
/* 1400 */ throw new IllegalStateException("Context does not exist with name: " + name);
/* 1401 */ return result;
/* */ }
/* */
/* */ protected void registerControllerContext(ControllerContext context)
/* */ {
/* 1415 */ if (context == null) {
/* 1416 */ throw new IllegalArgumentException("Null context");
/* */ }
/* 1418 */ Set aliases = context.getAliases();
/* */
/* 1421 */ Object name = context.getName();
/* 1422 */ registerControllerContext(name, context);
/* */
/* 1425 */ if ((aliases != null) && (!aliases.isEmpty()))
/* */ {
/* 1427 */ int ok = 0;
/* */ try
/* */ {
/* 1430 */ for (i$ = aliases.iterator(); i$.hasNext(); ) { Object alias = i$.next();
/* */
/* 1432 */ registerControllerContext(alias, context);
/* 1433 */ ok++;
/* */ }
/* */ }
/* */ finally
/* */ {
/* */ Iterator i$;
/* 1439 */ if ((ok != aliases.size()) && (ok > 0))
/* */ {
/* 1442 */ for (Iterator i$ = aliases.iterator(); i$.hasNext(); ) { Object alias = i$.next();
/* */
/* 1444 */ if (ok-- == 0)
/* */ break;
/* */ try
/* */ {
/* 1448 */ unregisterControllerContext(alias);
/* */ }
/* */ catch (Throwable ignored)
/* */ {
/* 1452 */ this.log.debug("Error unregistering alias: " + alias, ignored);
/* */ }
/* */
/* */ }
/* */
/* */ try
/* */ {
/* 1459 */ unregisterControllerContext(name);
/* */ }
/* */ catch (Throwable ignored)
/* */ {
/* 1463 */ this.log.debug("Error unregistering context with name: " + name, ignored);
/* */ }
/* */ }
/* */ }
/* */ }
/* */ }
/* */
/* */ protected void unregisterControllerContext(ControllerContext context)
/* */ {
/* 1481 */ if (context == null) {
/* 1482 */ throw new IllegalArgumentException("Null context");
/* */ }
/* 1484 */ Set aliases = context.getAliases();
/* */
/* 1487 */ Object name = context.getName();
/* 1488 */ unregisterControllerContext(name);
/* */ Iterator i$;
/* 1491 */ if ((aliases != null) && (!aliases.isEmpty()))
/* */ {
/* 1493 */ for (i$ = aliases.iterator(); i$.hasNext(); ) { Object alias = i$.next();
/* */ try
/* */ {
/* 1497 */ unregisterControllerContext(alias);
/* */ }
/* */ catch (Throwable ignored)
/* */ {
/* 1501 */ this.log.debug("Error unregistering alias: " + alias, ignored);
/* */ }
/* */ }
/* */ }
/* */ }
/* */
/* */ protected void registerControllerContext(Object name, ControllerContext context)
/* */ {
/* 1521 */ if (name == null)
/* 1522 */ throw new IllegalArgumentException("Null name");
/* 1523 */ if (context == null) {
/* 1524 */ throw new IllegalArgumentException("Null context");
/* */ }
/* 1526 */ if (!this.allContexts.containsKey(name))
/* 1527 */ this.allContexts.put(name, context);
/* */ else
/* 1529 */ throw new IllegalStateException("Unable to register context" + context.toShortString() + " name already exists: " + name);
/* */ }
/* */
/* */ protected void unregisterControllerContext(Object name)
/* */ {
/* 1544 */ if (name == null)
/* 1545 */ throw new IllegalArgumentException("Null name");
/* 1546 */ this.allContexts.remove(name);
/* */ }
/* */
/* */ private class AliasControllerContextAction extends SimpleControllerContextAction<AbstractController.AliasControllerContext>
/* */ {
/* */ private AliasControllerContextAction()
/* */ {
/* */ }
/* */
/* */ protected AbstractController.AliasControllerContext contextCast(ControllerContext context)
/* */ {
/* 1594 */ return (AbstractController.AliasControllerContext)AbstractController.AliasControllerContext.class.cast(context);
/* */ }
/* */
/* */ protected boolean validateContext(ControllerContext context)
/* */ {
/* 1599 */ return context instanceof AbstractController.AliasControllerContext;
/* */ }
/* */
/* */ protected void installAction(AbstractController.AliasControllerContext context) throws Throwable
/* */ {
/* 1604 */ Object alias = context.getAlias();
/* 1605 */ Object jmxAlias = JMXObjectNameFix.needsAnAlias(alias);
/* 1606 */ if (jmxAlias != null) {
/* 1607 */ alias = jmxAlias;
/* */ }
/* 1609 */ Object original = context.getOriginal();
/* 1610 */ Object jmxOriginal = JMXObjectNameFix.needsAnAlias(original);
/* 1611 */ if (jmxOriginal != null) {
/* 1612 */ original = jmxOriginal;
/* */ }
/* 1614 */ AbstractController.this.lockWrite();
/* */ try
/* */ {
/* 1617 */ ControllerContext lookup = AbstractController.this.getRegisteredControllerContext(original, true);
/* */
/* 1619 */ AbstractController.this.registerControllerContext(alias, lookup);
/* 1620 */ if (AbstractController.this.log.isTraceEnabled()) {
/* 1621 */ AbstractController.this.log.trace("Added alias " + alias + " for context " + context);
/* */ }
/* 1623 */ AbstractController.this.resolveContexts(AbstractController.this.log.isTraceEnabled());
/* */ }
/* */ finally
/* */ {
/* 1627 */ AbstractController.this.unlockWrite();
/* */ }
/* */ }
/* */
/* */ protected void uninstallAction(AbstractController.AliasControllerContext context)
/* */ {
/* 1633 */ AbstractController.this.lockWrite();
/* */ try
/* */ {
/* 1636 */ Object alias = context.getAlias();
/* 1637 */ Object jmxAlias = JMXObjectNameFix.needsAnAlias(alias);
/* 1638 */ if (jmxAlias != null) {
/* 1639 */ alias = jmxAlias;
/* */ }
/* 1641 */ AbstractController.this.unregisterControllerContext(alias);
/* 1642 */ if (AbstractController.this.log.isTraceEnabled())
/* 1643 */ AbstractController.this.log.trace("Removed alias " + alias);
/* */ }
/* */ finally
/* */ {
/* 1647 */ AbstractController.this.unlockWrite();
/* */ }
/* */ }
/* */ }
/* */
/* */ private class AliasControllerContext extends AbstractControllerContext
/* */ {
/* */ private Object alias;
/* */ private Object original;
/* */
/* */ public AliasControllerContext(Object alias, Object original, ControllerContextActions actions)
/* */ {
/* 1558 */ super(actions);
/* 1559 */ this.alias = alias;
/* 1560 */ this.original = original;
/* 1561 */ DependencyInfo info = getDependencyInfo();
/* 1562 */ info.addIDependOn(new AbstractDependencyItem(getName(), original, ControllerState.INSTALLED, ControllerState.INSTANTIATED));
/* */ }
/* */
/* */ public Object getAlias()
/* */ {
/* 1567 */ return this.alias;
/* */ }
/* */
/* */ public Object getOriginal()
/* */ {
/* 1572 */ return this.original;
/* */ }
/* */
/* */ public void toString(JBossStringBuilder buffer)
/* */ {
/* 1577 */ buffer.append("alias=").append(this.alias);
/* 1578 */ buffer.append(" original=").append(this.original).append(" ");
/* 1579 */ super.toString(buffer);
/* */ }
/* */
/* */ public void toShortString(JBossStringBuilder buffer)
/* */ {
/* 1584 */ buffer.append("alias=").append(this.alias);
/* 1585 */ buffer.append(" original=").append(this.original).append(" ");
/* 1586 */ super.toShortString(buffer);
/* */ }
/* */ }
/* */ }
/* Location: /home/mnovotny/projects/EMBEDDED_JBOSS_BETA3_COMMUNITY/embedded/output/lib/embedded-jboss/lib/jboss-embedded-all.jar
* Qualified Name: org.jboss.dependency.plugins.AbstractController
* JD-Core Version: 0.6.0
*/