/******************************************************************************* * 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; } }