package com.redhat.ceylon.eclipse.core.debug.preferences;
import static com.redhat.ceylon.eclipse.core.debug.preferences.CeylonDebugPreferenceInitializer.ACTIVE_FILTERS_LIST;
import static com.redhat.ceylon.eclipse.core.debug.preferences.CeylonDebugPreferenceInitializer.INACTIVE_FILTERS_LIST;
import static com.redhat.ceylon.eclipse.core.debug.preferences.CeylonDebugPreferenceInitializer.USE_STEP_FILTERS;
import static com.redhat.ceylon.eclipse.core.debug.preferences.CeylonDebugPreferenceInitializer.FILTER_DEFAULT_ARGUMENTS_CODE;
import static com.redhat.ceylon.eclipse.core.debug.preferences.CeylonDebugPreferenceInitializer.DEBUG_AS_JAVACODE;
import static org.eclipse.jdt.internal.debug.ui.JavaDebugOptionsManager.parseList;
import java.util.Arrays;
import org.eclipse.debug.core.DebugEvent;
import org.eclipse.debug.core.DebugPlugin;
import org.eclipse.debug.core.IDebugEventSetListener;
import org.eclipse.debug.core.ILaunch;
import org.eclipse.debug.core.ILaunchListener;
import org.eclipse.debug.core.model.IDebugTarget;
import org.eclipse.debug.internal.ui.DebugUIPlugin;
import org.eclipse.debug.ui.IDebugUIConstants;
import org.eclipse.debug.ui.IDebugView;
import org.eclipse.jface.preference.IPreferenceStore;
import org.eclipse.jface.util.IPropertyChangeListener;
import org.eclipse.jface.util.PropertyChangeEvent;
import org.eclipse.ui.IWorkbenchPage;
import com.redhat.ceylon.eclipse.core.debug.model.CeylonJDIDebugTarget;
import com.redhat.ceylon.eclipse.ui.CeylonPlugin;
/**
* Manages options for the Ceylon Debugger
*/
public class CeylonDebugOptionsManager
implements IDebugEventSetListener,
IPropertyChangeListener,
ILaunchListener {
/**
* Singleton options manager
*/
private static CeylonDebugOptionsManager optionsManager = null;
/**
* Whether the manager has been activated
*/
private boolean fActivated = false;
/**
* Not to be instantiated
*
* @see CeylonDebugOptionsManager#getDefault();
*/
private CeylonDebugOptionsManager() {
}
/**
* Return the default options manager
*/
public static CeylonDebugOptionsManager getDefault() {
if (optionsManager == null) {
optionsManager = new CeylonDebugOptionsManager();
}
return optionsManager;
}
/**
* Called at startup by the Java debug ui plug-in
*/
public void startup() {
// lazy initialization will occur on the first launch
DebugPlugin debugPlugin = DebugPlugin.getDefault();
debugPlugin.getLaunchManager().addLaunchListener(this);
}
/**
* Called at shutdown by the Ceylon plug-in
*/
public void shutdown() {
DebugPlugin debugPlugin = DebugPlugin.getDefault();
debugPlugin.getLaunchManager().removeLaunchListener(this);
debugPlugin.removeDebugEventListener(this);
CeylonPlugin.getPreferences().removePropertyChangeListener(this);
}
/**
* Notifies the give debug target of filter specifications
*
* @param target Ceylon debug target
*/
protected void notifyTargetOfPropertyChanges(CeylonJDIDebugTarget target) {
IPreferenceStore store = CeylonPlugin.getPreferences();
String[] filters = parseList(store.getString(ACTIVE_FILTERS_LIST));
target.setCeylonStepFilters(filters);
target.setCeylonStepFiltersEnabled(store.getBoolean(USE_STEP_FILTERS));
target.setFiltersDefaultArgumentsCode(store.getBoolean(FILTER_DEFAULT_ARGUMENTS_CODE));
target.setDebugAsJavaCode(store.getBoolean(DEBUG_AS_JAVACODE));
if (!registeredAsPropertyChangeListener) {
registeredAsPropertyChangeListener = true;
store.addPropertyChangeListener(this);
}
}
/**
* Notifies all targets of current filter specifications.
*/
protected void notifyTargetsOfPropertyChanges() {
IDebugTarget[] targets =
DebugPlugin.getDefault().getLaunchManager().getDebugTargets();
for (int i = 0; i < targets.length; i++) {
if (targets[i] instanceof CeylonJDIDebugTarget) {
CeylonJDIDebugTarget target =
(CeylonJDIDebugTarget) targets[i];
notifyTargetOfPropertyChanges(target);
}
}
}
/**
* @see IPropertyChangeListener#propertyChange(PropertyChangeEvent)
*/
public void propertyChange(PropertyChangeEvent event) {
String property = event.getProperty();
if (property.equals(DEBUG_AS_JAVACODE)) {
IWorkbenchPage page = DebugUIPlugin.getActiveWorkbenchWindow().getActivePage();
for (String viewId : Arrays.asList(
IDebugUIConstants.ID_VARIABLE_VIEW,
IDebugUIConstants.ID_EXPRESSION_VIEW,
IDebugUIConstants.ID_DEBUG_VIEW)) {
IDebugView view = (IDebugView) page.findView(viewId);
if (view != null) {
view.getViewer().refresh();
}
}
}
if (isPropertyForDebugTargets(property)) {
notifyTargetsOfPropertyChanges();
}
}
/**
* Returns whether the given property is a property that affects whether
* or not step filters are used.
*/
private boolean isPropertyForDebugTargets(String property) {
return property.equals(ACTIVE_FILTERS_LIST) ||
property.equals(INACTIVE_FILTERS_LIST) ||
property.equals(USE_STEP_FILTERS) ||
property.equals(FILTER_DEFAULT_ARGUMENTS_CODE) ||
property.equals(DEBUG_AS_JAVACODE);
}
private boolean registeredAsPropertyChangeListener = false;
/**
* When a Ceylon debug target is created, install options in
* the target.
*/
public void handleDebugEvents(DebugEvent[] events) {
for (int i = 0; i < events.length; i++) {
DebugEvent event = events[i];
if (event.getKind() == DebugEvent.CREATE) {
Object source = event.getSource();
if (source instanceof CeylonJDIDebugTarget) {
CeylonJDIDebugTarget ceylonTarget =
(CeylonJDIDebugTarget)source;
// step filters
notifyTargetOfPropertyChanges(ceylonTarget);
}
}
}
}
/**
* Activates this debug options manager. When active, this
* manager becomes a listener to many notifications and updates
* running debug targets based on these notifications.
*
* A debug options manager does not need to be activated until
* there is a running debug target.
*/
private void activate() {
if (fActivated) {
return;
}
fActivated = true;
notifyTargetsOfPropertyChanges();
DebugPlugin.getDefault().addDebugEventListener(this);
}
/**
* Startup problem handling on the first launch.
*
* @see ILaunchListener#launchAdded(ILaunch)
*/
public void launchAdded(ILaunch launch) {
launchChanged(launch);
}
public void launchChanged(ILaunch launch) {
activate();
DebugPlugin.getDefault().getLaunchManager().removeLaunchListener(this);
}
public void launchRemoved(ILaunch launch) {}
}