@Override
public Object run() {
State state = target.getState();
// The following states are illegal.
if (EnumSet.of(State.INSTALL_FAILED, State.UNINSTALLED, State.UNINSTALLING).contains(state))
throw new SubsystemException("Cannot stop from state " + state);
// The following states must wait.
if (EnumSet.of(State.INSTALLING, State.RESOLVING, State.STARTING, State.STOPPING).contains(state)) {
waitForStateChange();
return new StartAction(instigator, requestor, target).run();
}
// The following states mean the requested state has already been attained.
if (State.ACTIVE.equals(state))
return null;
// Always start if target is content of requestor.
if (!Utils.isContent(requestor, target)) {
// Aways start if target is a dependency of requestor.
if (!Utils.isDependency(requestor, target)) {
// Always start if instigator equals target (explicit start).
if (!instigator.equals(target)) {
// Don't start if instigator is root (restart) and target is not ready.
if (instigator.isRoot() && !target.isReadyToStart()) {
return null;
}
}
}
}
// Resolve if necessary.
if (State.INSTALLED.equals(state))
resolve(target);
target.setState(State.STARTING);
// TODO Need to hold a lock here to guarantee that another start
// operation can't occur when the state goes to RESOLVED.
// Start the subsystem.
Coordination coordination = Activator.getInstance()
.getCoordinator()
.create(target.getSymbolicName() + '-' + target.getSubsystemId(), 0);
try {
List<Resource> resources = new ArrayList<Resource>(Activator.getInstance().getSubsystems().getResourcesReferencedBy(target));
SubsystemContentHeader header = target.getSubsystemManifest().getSubsystemContentHeader();
if (header != null)
Collections.sort(resources, new StartResourceComparator(header));
for (Resource resource : resources)
startResource(resource, coordination);
target.setState(State.ACTIVE);
} catch (Throwable t) {
coordination.fail(t);
// TODO Need to reinstate complete isolation by disconnecting the
// region and transition to INSTALLED.
} finally {
try {
coordination.end();
} catch (CoordinationException e) {
target.setState(State.RESOLVED);
Throwable t = e.getCause();
if (t instanceof SubsystemException)
throw (SubsystemException)t;
throw new SubsystemException(t);
}
}
return null;
}