package org.marketcetera.photon.internal.strategy.ui; import java.util.List; import java.util.Set; import java.util.concurrent.atomic.AtomicReference; import org.eclipse.core.resources.IFile; import org.eclipse.core.resources.IResource; import org.eclipse.core.resources.IResourceVisitor; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.OperationCanceledException; import org.eclipse.core.runtime.Status; import org.eclipse.ltk.core.refactoring.Change; import org.eclipse.ltk.core.refactoring.CompositeChange; import org.eclipse.ltk.core.refactoring.RefactoringStatus; import org.eclipse.ltk.core.refactoring.participants.CheckConditionsContext; import org.eclipse.ltk.core.refactoring.participants.DeleteParticipant; import org.eclipse.ui.PlatformUI; import org.marketcetera.photon.strategy.StrategyUI; import org.marketcetera.photon.strategy.engine.IStrategyEngines; import org.marketcetera.photon.strategy.engine.model.core.DeployedStrategy; import org.marketcetera.photon.strategy.engine.model.core.StrategyEngine; import org.marketcetera.util.misc.ClassVersion; import com.google.common.collect.ImmutableList; import com.google.common.collect.Lists; import com.google.common.collect.Sets; import com.google.inject.Inject; import com.google.inject.Provider; /* $License$ */ /** * Undeploys local strategy deployments if they correspond to a file being * deleted. * * @author <a href="mailto:will@marketcetera.com">Will Horn</a> * @version $Id: UndeployDeleteParticipant.java 16154 2012-07-14 16:34:05Z colin $ * @since 2.0.0 */ @ClassVersion("$Id: UndeployDeleteParticipant.java 16154 2012-07-14 16:34:05Z colin $") public class UndeployDeleteParticipant extends DeleteParticipant { private static final String PLATFORM_RESOURCE_URL_PREFIX = "platform:/resource"; //$NON-NLS-1$ private final Provider<IStrategyEngines> mEnginesProvider; private volatile ImmutableList<DeployedStrategy> mAffected; private volatile String mResourcePath; /** * Constructor. * * @param enginesProvider * provides access to the strategy engines */ @Inject public UndeployDeleteParticipant(Provider<IStrategyEngines> enginesProvider) { mEnginesProvider = enginesProvider; } @Override public RefactoringStatus checkConditions(IProgressMonitor pm, CheckConditionsContext context) throws OperationCanceledException { return new RefactoringStatus(); } @Override public Change createChange(IProgressMonitor pm) throws CoreException, OperationCanceledException { Change[] changes = new Change[mAffected.size()]; for (int i = 0; i < changes.length; i++) { changes[i] = new UndeployChange(mAffected.get(i)); } return new CompositeChange( Messages.UNDEPLOY_DELETE_PARTICIPANT_CHANGE_GROUP__DESCRIPTION .getText(mResourcePath), changes); } @Override public String getName() { return Messages.UNDEPLOY_DELETE_PARTICIPANT__NAME.getText(); } @Override protected boolean initialize(final Object element) { final IStrategyEngines engines = mEnginesProvider.get(); if (engines != null) { final AtomicReference<CoreException> exception = new AtomicReference<CoreException>(); PlatformUI.getWorkbench().getDisplay().syncExec(new Runnable() { @Override public void run() { if (engines.getStrategyEngines().size() > 0) { final Set<String> affectedFiles = Sets.newHashSet(); IResource resource = (IResource) element; mResourcePath = resource.getFullPath().toString(); try { resource.accept(new IResourceVisitor() { @Override public boolean visit(IResource resource) throws CoreException { if (resource instanceof IFile) { affectedFiles .add(PLATFORM_RESOURCE_URL_PREFIX + ((IFile) resource) .getFullPath() .toString()); return false; } return true; } }); } catch (CoreException e) { exception.set(e); return; } if (!affectedFiles.isEmpty()) { List<DeployedStrategy> strategies = Lists .newLinkedList(); StrategyEngine embeddedEngine = (StrategyEngine) engines .getStrategyEngines().get(0); for (DeployedStrategy strategy : embeddedEngine .getDeployedStrategies()) { if (affectedFiles.contains(strategy .getScriptPath())) { strategies.add(strategy); } } if (!strategies.isEmpty()) { mAffected = ImmutableList.copyOf(strategies); } } } } }); CoreException caughtException = exception.get(); if (caughtException != null) { // this is not expected to happen throw new IllegalStateException(caughtException); } } return mAffected != null; } /** * Undeploys a single strategy. */ @ClassVersion("$Id: UndeployDeleteParticipant.java 16154 2012-07-14 16:34:05Z colin $") private static class UndeployChange extends Change { private final DeployedStrategy mStrategy; /** * Constructor. * * @param strategy * the strategy to undeploy */ public UndeployChange(DeployedStrategy strategy) { mStrategy = strategy; } @Override public Change perform(IProgressMonitor pm) throws CoreException { try { mStrategy.getEngine().getConnection().undeploy(mStrategy); } catch (Exception e) { throw new CoreException(new Status(IStatus.ERROR, StrategyUI.PLUGIN_ID, e.getLocalizedMessage(), e)); } // no undo support return null; } @Override public RefactoringStatus isValid(IProgressMonitor pm) throws CoreException, OperationCanceledException { return RefactoringStatus.create(Status.OK_STATUS); } @Override public void initializeValidationData(IProgressMonitor pm) { } @Override public String getName() { return Messages.UNDEPLOY_DELETE_PARTICIPANT_CHANGE__DESCRIPTION .getText(mStrategy.getInstanceName(), mStrategy.getEngine() .getName()); } @Override public Object getModifiedElement() { return null; } } }