/*******************************************************************************
* Copyright (c) 2007, 2016 Wind River Systems and others.
* 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:
* Wind River Systems - initial API and implementation
* Ericsson - Added tracepoint support (284286)
* Marc Khouzam (Ericsson) - Added dynamic printf support (400628)
*******************************************************************************/
package org.eclipse.cdt.debug.internal.ui.breakpoints;
import java.util.Map;
import org.eclipse.cdt.debug.core.CDIDebugModel;
import org.eclipse.cdt.debug.core.model.ICAddressBreakpoint;
import org.eclipse.cdt.debug.core.model.ICBreakpoint;
import org.eclipse.cdt.debug.core.model.ICDynamicPrintf;
import org.eclipse.cdt.debug.core.model.ICEventBreakpoint;
import org.eclipse.cdt.debug.core.model.ICFunctionBreakpoint;
import org.eclipse.cdt.debug.core.model.ICLineBreakpoint;
import org.eclipse.cdt.debug.core.model.ICTracepoint;
import org.eclipse.cdt.debug.core.model.ICWatchpoint;
import org.eclipse.cdt.debug.ui.breakpoints.ICBreakpointContext;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.runtime.IAdaptable;
import org.eclipse.core.runtime.IAdapterFactory;
import org.eclipse.core.runtime.Platform;
import org.eclipse.core.runtime.PlatformObject;
import org.eclipse.debug.core.model.IBreakpoint;
import org.eclipse.debug.core.model.IDebugElement;
import org.eclipse.debug.core.model.IDebugModelProvider;
import org.eclipse.debug.ui.contexts.IDebugContextListener;
import org.eclipse.jface.preference.IPreferenceStore;
import org.eclipse.jface.resource.ImageDescriptor;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.ui.IActionFilter;
import org.eclipse.ui.IWorkbenchPart;
import org.eclipse.ui.model.IWorkbenchAdapter;
/**
* Input for breakpoint properties dialog. It captures both the
* selected breakpoint object as well as the selected debug context.
* This combined context can then be used by breakpoint property
* pages to access model and target specific breakpoint settings.
*/
public class CBreakpointContext extends PlatformObject implements ICBreakpointContext {
// Register an adapter factory for the class when it is first loaded.
static {
Platform.getAdapterManager().registerAdapters(new CBreakpointContextAdapterFactory(), CBreakpointContext.class);
}
/**
* Breakpoint object held by this context.
*/
private final ICBreakpoint fBreakpoint;
/**
* The resource that the breakpoint is to be created for.
*/
private final IResource fResource;
/**
* The active debug context held by this context.
*/
private final ISelection fDebugContext;
/**
* Associated preference store.
*/
private final CBreakpointPreferenceStore fPreferenceStore;
/**
* Creates a new breakpoint context with given breakpoint and debug
* context selection.
*/
public CBreakpointContext(ICBreakpoint breakpoint, ISelection debugContext) {
this (breakpoint, debugContext, null, null);
}
public CBreakpointContext(ICBreakpoint breakpoint, ISelection debugContext, IResource resource, Map<String, Object> attributes) {
fBreakpoint = breakpoint;
fResource = resource;
fDebugContext = debugContext;
fPreferenceStore = new CBreakpointPreferenceStore(this, attributes);
}
@Override
public ICBreakpoint getBreakpoint() { return fBreakpoint; }
@Override
public IResource getResource() { return fResource; }
@Override
public IPreferenceStore getPreferenceStore() { return fPreferenceStore; }
/**
* Returns the debug context.
*/
public ISelection getDebugContext() { return fDebugContext; }
/**
* (non-Javadoc)
* @see org.eclipse.debug.ui.contexts.IDebugContextProvider implementation
*/
public IWorkbenchPart getPart() { return null; }
public void addDebugContextListener(IDebugContextListener listener) {}
public void removeDebugContextListener(IDebugContextListener listener) {}
public ISelection getActiveContext() {
return fDebugContext;
}
}
/**
* Action filter for the breakpoint context, which allows property
* pages to filter their activation based on the debug model ID of
* the active debug context.
*/
class CBreakpointContextActionFilter implements IActionFilter {
private static String[] EMPTY_IDENTIFIERS_ARRAY = new String[0];
@Override
public boolean testAttribute(Object target, String name, String value) {
if (target instanceof CBreakpointContext) {
if ("debugModelId".equals(name)) { //$NON-NLS-1$
String[] targetModelIds = getDebugModelIds( (CBreakpointContext)target );
for (int i = 0; i < targetModelIds.length; i++) {
if (targetModelIds[i].equals(value)) {
return true;
}
}
}
}
return false;
}
private String[] getDebugModelIds(CBreakpointContext bpContext) {
ISelection debugContext = bpContext.getDebugContext();
if (debugContext instanceof IStructuredSelection) {
Object debugElement = ((IStructuredSelection)debugContext).getFirstElement();
if (debugElement instanceof IAdaptable) {
IDebugModelProvider debugModelProvider =
((IAdaptable)debugElement).getAdapter(IDebugModelProvider.class);
if (debugModelProvider != null) {
return debugModelProvider.getModelIdentifiers();
} else if (debugElement instanceof IDebugElement) {
return new String[] { ((IDebugElement)debugElement).getModelIdentifier() };
}
}
}
return EMPTY_IDENTIFIERS_ARRAY;
}
}
class CBreakpointContextWorkbenchAdapter implements IWorkbenchAdapter {
@Override
public String getLabel(Object o) {
if (o instanceof ICBreakpointContext) {
ICBreakpoint bp = ((ICBreakpointContext)o).getBreakpoint();
return getBreakpointMainLabel(bp);
}
return ""; //$NON-NLS-1$
}
@Override
public Object[] getChildren(Object o) { return null; }
@Override
public ImageDescriptor getImageDescriptor(Object object) { return null; }
@Override
public Object getParent(Object o) { return null; }
private String getBreakpointMainLabel(ICBreakpoint breakpoint) {
if (breakpoint instanceof ICFunctionBreakpoint) {
if (breakpoint instanceof ICTracepoint) {
return BreakpointsMessages.getString("TracepointPropertyPage.tracepointType_function_label"); //$NON-NLS-1$
} else if (breakpoint instanceof ICDynamicPrintf) {
return BreakpointsMessages.getString("DPrintfPropertyPage.dprintfType_function_label"); //$NON-NLS-1$
} else {
return BreakpointsMessages.getString("CBreakpointPropertyPage.breakpointType_function_label"); //$NON-NLS-1$
}
} else if (breakpoint instanceof ICAddressBreakpoint) {
if (breakpoint instanceof ICTracepoint) {
return BreakpointsMessages.getString("TracepointPropertyPage.tracepointType_address_label"); //$NON-NLS-1$
} else if (breakpoint instanceof ICDynamicPrintf) {
return BreakpointsMessages.getString("DPrintfPropertyPage.dprintfType_address_label"); //$NON-NLS-1$
} else {
return BreakpointsMessages.getString("CBreakpointPropertyPage.breakpointType_address_label"); //$NON-NLS-1$
}
} else if (breakpoint instanceof ICLineBreakpoint) {
if (breakpoint instanceof ICTracepoint) {
return BreakpointsMessages.getString("TracepointPropertyPage.tracepointType_line_label"); //$NON-NLS-1$
} else if (breakpoint instanceof ICDynamicPrintf) {
return BreakpointsMessages.getString("DPrintfPropertyPage.dprintfType_line_label"); //$NON-NLS-1$
} else {
return BreakpointsMessages.getString("CBreakpointPropertyPage.breakpointType_line_label"); //$NON-NLS-1$
}
} else if (breakpoint instanceof ICEventBreakpoint) {
return BreakpointsMessages.getString("CBreakpointPropertyPage.breakpointType_event_label"); //$NON-NLS-1$
} else if (breakpoint instanceof ICWatchpoint) {
return BreakpointsMessages.getString("CBreakpointPropertyPage.breakpointType_watchpoint_label"); //$NON-NLS-1$
}
// default main label is the label of marker type for the breakpoint
return CDIDebugModel.calculateMarkerType(breakpoint);
}
}
/**
* Adapter factory which returns the breakpoint object and the action
* filter for the CBreakpointContext type.
*/
class CBreakpointContextAdapterFactory implements IAdapterFactory {
private static final Class<?>[] fgAdapterList = new Class[] {
IBreakpoint.class, ICBreakpoint.class, ICTracepoint.class, ICDynamicPrintf.class,
IActionFilter.class, IPreferenceStore.class, IWorkbenchAdapter.class,
};
private static final IActionFilter fgActionFilter = new CBreakpointContextActionFilter();
private static final IWorkbenchAdapter fgWorkbenchAdapter = new CBreakpointContextWorkbenchAdapter();
@SuppressWarnings("unchecked")
@Override
public <T> T getAdapter(Object obj, Class<T> adapterType) {
// Note: only return the breakpoint object as an adapter if it has
// an associated marker. Otherwise the property pages will throw multiple
// exceptions.
if (adapterType.isInstance( ((CBreakpointContext)obj).getBreakpoint() ) &&
((CBreakpointContext)obj).getBreakpoint().getMarker() != null)
{
return (T) ((CBreakpointContext)obj).getBreakpoint();
}
if ( IPreferenceStore.class.equals(adapterType) ) {
return (T) ((CBreakpointContext)obj).getPreferenceStore();
}
if (IActionFilter.class.equals(adapterType)) {
return (T) fgActionFilter;
}
if (IWorkbenchAdapter.class.equals(adapterType)) {
return (T) fgWorkbenchAdapter;
}
return null;
}
@Override
public Class<?>[] getAdapterList() {
return fgAdapterList;
}
}