/*******************************************************************************
* Copyright (c) 2015 Pivotal Software, Inc.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Pivotal Software, Inc. - initial API and implementation
*******************************************************************************/
package org.springframework.ide.eclipse.boot.dash.cloudfoundry.debug;
import java.util.Map;
import org.eclipse.debug.core.ILaunch;
import org.eclipse.debug.core.model.IDebugTarget;
import org.eclipse.debug.core.model.IProcess;
import org.springframework.ide.eclipse.boot.dash.cloudfoundry.CloudAppDashElement;
import org.springframework.ide.eclipse.boot.dash.cloudfoundry.ops.Operation;
import org.springframework.ide.eclipse.boot.dash.model.BootDashModel;
import org.springframework.ide.eclipse.boot.dash.model.BootDashViewModel;
import org.springframework.ide.eclipse.boot.dash.model.UserInteractions;
import org.springframework.ide.eclipse.boot.dash.util.CancelationTokens.CancelationToken;
import org.springframework.ide.eclipse.boot.util.ProcessListenerAdapter;
import org.springframework.ide.eclipse.boot.util.ProcessTracker;
/**
* Abstract class that must be implemented to add debug support to a CF application.
*
* @author Kris De Volder
*/
public abstract class DebugSupport {
/**
* Determine whether debugging can be supported (using the strategy impemented by this DebugSupport instance)
*/
public abstract boolean isSupported(CloudAppDashElement app);
/**
* If isSupported returns false than the support strategy may also return an explanation why the strategy is not
* supported (e.g. PCF version too old, SSH support disabled etc.)
*/
public abstract String getNotSupportedMessage(CloudAppDashElement app);
/**
* Creates operation that does whatever is needed to get debugger connected to the targetted app.
*/
public abstract Operation<?> createOperation(CloudAppDashElement app, String opName, UserInteractions ui, CancelationToken cancelToken);
/**
* Called to allow debug support to muck around with environment variables so that it can
* do things like add debugging options to 'JAVA_OPTS'.
*/
public abstract void setupEnvVars(Map<String, String> environmentVariables);
/**
* Like setupEnvVars, but called when debugging is disabled. The debug strategy should try to
* undo any changes it made to the env vars to enable debugging.
*/
public abstract void clearEnvVars(Map<String, String> environmentVariables);
/**
* Determines whether debugger is currently attached to the targetted app.
*/
public abstract boolean isDebuggerAttached(CloudAppDashElement app);
/**
* A debug strategy typically involves creating some type of launch that establishes
* a debug connection. To be able to update the debug state in response to changes in
* launches, its necessary to be able to determine what dashboard element corresponds to
* a given launch. Therefore a debug strategy must implement this method.
*
* @return The corresponding CDE for a given launch, or null
*/
public abstract CloudAppDashElement getElementFor(ILaunch l, BootDashViewModel viewModel);
/**
* Provides a process tracker. Subclasses may override if the default implementation is not suitable.
* <p>
* The process tracker is responsible to listen for changes in the Eclipse debug ui so it can make
* bootdash elements 'debug' state update when processes and/or debug targets are created or terminated.
*/
public ProcessTracker createProcessTracker(final BootDashViewModel viewModel) {
return new ProcessTracker(new ProcessListenerAdapter() {
@Override
public void debugTargetCreated(ProcessTracker tracker, IDebugTarget target) {
handleStateChange(target.getLaunch());
}
@Override
public void debugTargetTerminated(ProcessTracker tracker, IDebugTarget target) {
handleStateChange(target.getLaunch());
}
@Override
public void processTerminated(ProcessTracker tracker, IProcess process) {
//Typically a debug strategy only needs to care about debugtargets, not IProcesses.
// So nothing to do here.
}
@Override
public void processCreated(ProcessTracker tracker, IProcess process) {
//Typically a debug strategy only needs to care about debugtargets, not IProcesses.
// So nothing to do here.
}
private void handleStateChange(ILaunch l) {
CloudAppDashElement e = getElementFor(l, viewModel);
if (e!=null) {
BootDashModel model = e.getBootDashModel();
model.notifyElementChanged(e);
}
}
});
}
}