diff --git a/dsf/org.eclipse.cdt.dsf.ui/src/org/eclipse/cdt/dsf/debug/ui/viewmodel/breakpoints/BreakpointVMProvider.java b/dsf/org.eclipse.cdt.dsf.ui/src/org/eclipse/cdt/dsf/debug/ui/viewmodel/breakpoints/BreakpointVMProvider.java index f59b147c289..ee8c2a2c1b7 100644 --- a/dsf/org.eclipse.cdt.dsf.ui/src/org/eclipse/cdt/dsf/debug/ui/viewmodel/breakpoints/BreakpointVMProvider.java +++ b/dsf/org.eclipse.cdt.dsf.ui/src/org/eclipse/cdt/dsf/debug/ui/viewmodel/breakpoints/BreakpointVMProvider.java @@ -1,382 +1,382 @@ -/******************************************************************************* - * Copyright (c) 2006, 2008 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 - *******************************************************************************/ -package org.eclipse.cdt.dsf.debug.ui.viewmodel.breakpoints; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.Comparator; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import org.eclipse.cdt.dsf.concurrent.DataRequestMonitor; -import org.eclipse.cdt.dsf.concurrent.DsfRunnable; -import org.eclipse.cdt.dsf.concurrent.IDsfStatusConstants; -import org.eclipse.cdt.dsf.concurrent.RequestMonitor; -import org.eclipse.cdt.dsf.datamodel.DMContexts; -import org.eclipse.cdt.dsf.datamodel.IDMContext; -import org.eclipse.cdt.dsf.debug.service.IBreakpoints.IBreakpointsTargetDMContext; -import org.eclipse.cdt.dsf.debug.ui.viewmodel.expression.IExpressionVMNode; -import org.eclipse.cdt.dsf.internal.ui.DsfUIPlugin; -import org.eclipse.cdt.dsf.ui.viewmodel.AbstractVMAdapter; -import org.eclipse.cdt.dsf.ui.viewmodel.AbstractVMProvider; -import org.eclipse.cdt.dsf.ui.viewmodel.IVMModelProxy; -import org.eclipse.cdt.dsf.ui.viewmodel.IVMNode; -import org.eclipse.cdt.dsf.ui.viewmodel.datamodel.IDMVMContext; -import org.eclipse.cdt.dsf.ui.viewmodel.datamodel.RootDMVMNode; -import org.eclipse.core.resources.IMarkerDelta; -import org.eclipse.core.runtime.IAdaptable; -import org.eclipse.core.runtime.IStatus; -import org.eclipse.core.runtime.Status; -import org.eclipse.debug.core.DebugPlugin; -import org.eclipse.debug.core.IBreakpointsListener; -import org.eclipse.debug.core.model.IBreakpoint; -import org.eclipse.debug.internal.ui.breakpoints.provisional.IBreakpointOrganizer; -import org.eclipse.debug.internal.ui.breakpoints.provisional.IBreakpointUIConstants; -import org.eclipse.debug.internal.ui.breakpoints.provisional.OtherBreakpointCategory; -import org.eclipse.debug.internal.ui.elements.adapters.DefaultBreakpointsViewInput; -import org.eclipse.debug.internal.ui.viewers.model.provisional.IColumnPresentation; -import org.eclipse.debug.internal.ui.viewers.model.provisional.IModelDelta; -import org.eclipse.debug.internal.ui.viewers.model.provisional.IPresentationContext; -import org.eclipse.debug.internal.ui.viewers.model.provisional.IViewerInputUpdate; -import org.eclipse.debug.ui.DebugUITools; -import org.eclipse.debug.ui.IBreakpointOrganizerDelegate; -import org.eclipse.debug.ui.contexts.DebugContextEvent; -import org.eclipse.debug.ui.contexts.IDebugContextListener; -import org.eclipse.jface.util.IPropertyChangeListener; -import org.eclipse.jface.util.PropertyChangeEvent; -import org.eclipse.jface.viewers.ISelection; -import org.eclipse.jface.viewers.TreePath; -import org.eclipse.ui.IWorkbenchWindow; - -/** - * The expression provider is used to populate the contents of the expressions - * view. The node hierarchy in this view is a little different than in a typical - * provider: the expression manager node should be registered as the single child - * of the root node and no nodes should be registered as children of expression node. - * Instead the top level expression nodes should be registered with a call to - * {@link #setExpressionNodes(IExpressionVMNode[])}. And each expression node can - * have its own sub-hierarchy of elements as needed. However all nodes configured - * with this provider (with the exception of the root and the expression manager) - * should implement {@link IExpressionVMNode}. - * - * @since 2.1 - */ -public class BreakpointVMProvider extends AbstractVMProvider -{ - private IPropertyChangeListener fPresentationContextListener = new IPropertyChangeListener() { - public void propertyChange(PropertyChangeEvent event) { - handleEventInExecThread(event); - } - }; - - private IBreakpointsListener fBreakpointsListener = new IBreakpointsListener() { - public void breakpointsRemoved(IBreakpoint[] breakpoints, IMarkerDelta[] deltas) { - handleEventInExecThread(new BreakpointsChangedEvent(BreakpointsChangedEvent.Type.REMOVED, breakpoints)); - } - - public void breakpointsChanged(IBreakpoint[] breakpoints, IMarkerDelta[] deltas) { - handleEventInExecThread(new BreakpointsChangedEvent(BreakpointsChangedEvent.Type.CHANGED, breakpoints)); - } - - public void breakpointsAdded(IBreakpoint[] breakpoints) { - handleEventInExecThread(new BreakpointsChangedEvent(BreakpointsChangedEvent.Type.ADDED, breakpoints)); - } - - }; - - private IDebugContextListener fDebugContextListener = new IDebugContextListener() { - public void debugContextChanged(final DebugContextEvent event) { - handleEventInExecThread(event); - } - }; - - private class ContainerBreakpointsCache extends DataCache> { - - private BreakpointOrganizerVMNode fOrganizerVMNode; - private TreePath fParentPath; - - public ContainerBreakpointsCache(BreakpointOrganizerVMNode organizerVMNode, TreePath parentPath) { - super(getExecutor()); - fOrganizerVMNode = organizerVMNode; - fParentPath = parentPath; - } - - @Override - protected void retrieve(final DataRequestMonitor> rm) { - getNestingCategoryBreakpoints( - fParentPath, - new DataRequestMonitor(getExecutor(), rm) { - @SuppressWarnings({ "cast", "unchecked" }) - @Override - protected void handleSuccess() { - Map> bpsLists = new HashMap>(); - for (IBreakpoint bp : getData()) { - IAdaptable[] bpCategories = fOrganizerVMNode.getOrganizer().getCategories(bp); - if (bpCategories == null || bpCategories.length == 0) { - bpCategories = OtherBreakpointCategory.getCategories(fOrganizerVMNode.getOrganizer()); - } - - for (IAdaptable category : bpCategories) { - List categoryBPs = bpsLists.get(category); - if (categoryBPs == null) { - categoryBPs = new ArrayList(); - bpsLists.put(category, categoryBPs); - } - categoryBPs.add(bp); - } - } - - // Only show the empty containers for the top-level node. - if (fParentPath.getSegmentCount() == 0) { - final IAdaptable[] independentCategories = fOrganizerVMNode.getOrganizer().getCategories(); - if (independentCategories != null) { - for (IAdaptable category : independentCategories) { - if (!bpsLists.containsKey(category)) { - bpsLists.put(category, (List)Collections.EMPTY_LIST); - } - } - } - } - - List vmcs = new ArrayList(bpsLists.size()); - for (Map.Entry> entry : bpsLists.entrySet()) { - List bpsList = entry.getValue(); - IBreakpoint[] bpsArray = bpsList.toArray(new IBreakpoint[bpsList.size()]); - - vmcs.add(createBreakpointOrganizerVMContext(fOrganizerVMNode, entry.getKey(), bpsArray)); - } - Comparator comparator = (Comparator)getPresentationContext().getProperty( - IBreakpointUIConstants.PROP_BREAKPOINTS_ELEMENT_COMPARATOR); - if (comparator != null) { - Collections.sort(vmcs, comparator); - } - - rm.setData(vmcs); - rm.done(); - } - }); - } - }; - - private final Map fContainerBreakpointsCacheMap = - new HashMap(); - - private DataCache fFilteredBreakpointsCache = new DataCache(getExecutor()) { - @Override - protected void retrieve(org.eclipse.cdt.dsf.concurrent.DataRequestMonitor rm) { - calcFileteredBreakpoints(rm); - } - }; - - public BreakpointVMProvider(AbstractVMAdapter adapter, IPresentationContext context) { - super(adapter, context); - - // Create the top level node which provides the anchor starting point. - // This node is referenced by the BreakpointVMInput element so it - // should not change when the view layout is updated. - setRootNode(new RootDMVMNode(this)); - // Configure the rest of the layout nodes. - configureLayout(); - - context.addPropertyChangeListener(fPresentationContextListener); - DebugPlugin.getDefault().getBreakpointManager().addBreakpointListener(fBreakpointsListener); - IWorkbenchWindow window = context.getWindow(); - if (window != null) { - DebugUITools.getDebugContextManager().getContextService(window).addDebugContextListener( - fDebugContextListener); - } - - } - - @Override - protected IVMModelProxy createModelProxyStrategy(Object rootElement) { - return new BreakpointVMModelProxyStrategy(this, rootElement); - } - - protected IVMNode createBreakpointVMNode() { - return new BreakpointVMNode(this); - } - - /** - * Configures the nodes of this provider. This method may be over-ridden by - * sub classes to create an alternate configuration in this provider. - */ - protected void configureLayout() { - IBreakpointOrganizer[] organizers = (IBreakpointOrganizer[]) - getPresentationContext().getProperty(IBreakpointUIConstants.PROP_BREAKPOINTS_ORGANIZERS); - - IVMNode parentNode = getRootVMNode(); - if (organizers != null) { - for (IBreakpointOrganizer organizer : organizers) { - IVMNode organizerNode = new BreakpointOrganizerVMNode(this, organizer); - addChildNodes(parentNode, new IVMNode[] {organizerNode}); - parentNode = organizerNode; - } - } - - IVMNode bpsNode = createBreakpointVMNode(); - addChildNodes(parentNode, new IVMNode[] {bpsNode}); - } - - - @Override - public void dispose() { - getPresentationContext().removePropertyChangeListener(fPresentationContextListener); - DebugPlugin.getDefault().getBreakpointManager().removeBreakpointListener(fBreakpointsListener); - IWorkbenchWindow window = getPresentationContext().getWindow(); - if (window != null) { - DebugUITools.getDebugContextManager().getContextService(window).addDebugContextListener( - fDebugContextListener); - } - super.dispose(); - } - - @Override - public IColumnPresentation createColumnPresentation(IPresentationContext context, Object element) { - return null; - } - - @Override - public String getColumnPresentationId(IPresentationContext context, Object element) { - return null; - } - - @Override - public void update(IViewerInputUpdate update) { - IDMContext activeDMContext = null; - if (update.getElement() instanceof IDMVMContext) { - activeDMContext = ((IDMVMContext)update.getElement()).getDMContext(); - activeDMContext = DMContexts.getAncestorOfType(activeDMContext, IBreakpointsTargetDMContext.class); - } - if (activeDMContext != null) { - update.setInputElement(new BreakpointVMInput(getRootVMNode(), activeDMContext)); - } else { - // If no breakpoints target found in active context, delegate the breakpoint - // presentation to the default: breakpoint manager. - update.setInputElement(new DefaultBreakpointsViewInput(update.getPresentationContext())); - } - update.done(); - } - - public void getNestingCategoryBreakpoints(TreePath path, final DataRequestMonitor rm) { - BreakpointOrganizerVMContext nestingOrganizerVmc = null; - while (path.getSegmentCount() > 0) { - if (path.getLastSegment() instanceof BreakpointOrganizerVMContext) { - nestingOrganizerVmc = (BreakpointOrganizerVMContext)path.getLastSegment(); - break; - } - path = path.getParentPath(); - } - if (nestingOrganizerVmc == null) { - getFileteredBreakpoints(rm); - } else { - final BreakpointOrganizerVMContext _nestingOrganizerVmc = nestingOrganizerVmc; - getBreakpointOrganizerVMCs( - (BreakpointOrganizerVMNode)_nestingOrganizerVmc.getVMNode(), path.getParentPath(), - new DataRequestMonitor>(getExecutor(), rm) { - @Override - protected void handleSuccess() { - int newVmcIdx = getData().indexOf(_nestingOrganizerVmc); - - if (newVmcIdx >= 0) { - rm.setData(getData().get(newVmcIdx).getBreakpoints()); - } else { - rm.setStatus(new Status(IStatus.ERROR, DsfUIPlugin.PLUGIN_ID, IDsfStatusConstants.INVALID_HANDLE, "Breakpoint category not found", null)); //$NON-NLS-1$ - } - rm.done(); - } - }); - } - } - - public void getBreakpointOrganizerVMCs(BreakpointOrganizerVMNode organizerVMNode, TreePath path, - DataRequestMonitor> rm) - { - ContainerBreakpointsCache cache = fContainerBreakpointsCacheMap.get(path); - if (cache == null) { - cache = new ContainerBreakpointsCache(organizerVMNode, path); - fContainerBreakpointsCacheMap.put(path, cache); - } - - cache.request(rm); - } - - - protected BreakpointOrganizerVMContext createBreakpointOrganizerVMContext(BreakpointOrganizerVMNode node, IAdaptable category, IBreakpoint[] breakpoints) { - return new BreakpointOrganizerVMContext(node, category, breakpoints); - } - - - public void getFileteredBreakpoints(final DataRequestMonitor rm) { - fFilteredBreakpointsCache.request(rm); - } - - protected void calcFileteredBreakpoints(DataRequestMonitor rm) { - rm.setData(DebugPlugin.getDefault().getBreakpointManager().getBreakpoints()); - rm.done(); - } - - public void getBreakpointsForDebugContext(ISelection debugContext, DataRequestMonitor rm) { - rm.setStatus(new Status(IStatus.ERROR, DsfUIPlugin.PLUGIN_ID, IDsfStatusConstants.NOT_SUPPORTED, "Not supported", null)); //$NON-NLS-1$ - rm.done(); - } - - public void handleEventInExecThread(final Object event) { - getExecutor().execute(new DsfRunnable() { - public void run() { - handleEvent(event); - } - }); - } - - @Override - public void handleEvent(Object event, RequestMonitor rm) { - if (isPresentationContextEvent(event)) { - PropertyChangeEvent propertyEvent = (PropertyChangeEvent)event; - if (IBreakpointUIConstants.PROP_BREAKPOINTS_ORGANIZERS.equals(propertyEvent.getProperty())) - { - clearNodes(false); - configureLayout(); - } - } - super.handleEvent(event, rm); - } - - public static boolean isPresentationContextEvent(Object event) { - return event instanceof PropertyChangeEvent && ((PropertyChangeEvent)event).getSource() instanceof IPresentationContext; - } - - public static boolean isBreakpointOrganizerEvent(Object event) { - return event instanceof PropertyChangeEvent && ((PropertyChangeEvent)event).getSource() instanceof IBreakpointOrganizerDelegate; - } - - private static final int MODEL_DELTA_CHANGE_FLAGS = IModelDelta.STATE | IModelDelta.CONTENT | IModelDelta.ADDED | IModelDelta.REMOVED | IModelDelta.REPLACED | IModelDelta.INSERTED; - - @Override - protected void handleEvent(IVMModelProxy proxyStrategy, Object event, RequestMonitor rm) { - // Before generating a delta, flush the caches. - int deltaFlags = proxyStrategy.getEventDeltaFlags(event); - if ((deltaFlags & MODEL_DELTA_CHANGE_FLAGS) != 0) { - flushCaches(); - } - - super.handleEvent(proxyStrategy, event, rm); - } - - private void flushCaches() { - fFilteredBreakpointsCache.reset(); - for (DataCache cache : fContainerBreakpointsCacheMap.values()) { - cache.reset(); - } - fContainerBreakpointsCacheMap.clear(); - } -} +/******************************************************************************* + * Copyright (c) 2006, 2008 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 + *******************************************************************************/ +package org.eclipse.cdt.dsf.debug.ui.viewmodel.breakpoints; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.Comparator; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.eclipse.cdt.dsf.concurrent.DataRequestMonitor; +import org.eclipse.cdt.dsf.concurrent.DsfRunnable; +import org.eclipse.cdt.dsf.concurrent.IDsfStatusConstants; +import org.eclipse.cdt.dsf.concurrent.RequestMonitor; +import org.eclipse.cdt.dsf.datamodel.DMContexts; +import org.eclipse.cdt.dsf.datamodel.IDMContext; +import org.eclipse.cdt.dsf.debug.service.IBreakpoints.IBreakpointsTargetDMContext; +import org.eclipse.cdt.dsf.debug.ui.viewmodel.expression.IExpressionVMNode; +import org.eclipse.cdt.dsf.internal.ui.DsfUIPlugin; +import org.eclipse.cdt.dsf.ui.viewmodel.AbstractVMAdapter; +import org.eclipse.cdt.dsf.ui.viewmodel.AbstractVMProvider; +import org.eclipse.cdt.dsf.ui.viewmodel.IVMModelProxy; +import org.eclipse.cdt.dsf.ui.viewmodel.IVMNode; +import org.eclipse.cdt.dsf.ui.viewmodel.datamodel.IDMVMContext; +import org.eclipse.cdt.dsf.ui.viewmodel.datamodel.RootDMVMNode; +import org.eclipse.core.resources.IMarkerDelta; +import org.eclipse.core.runtime.IAdaptable; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Status; +import org.eclipse.debug.core.DebugPlugin; +import org.eclipse.debug.core.IBreakpointsListener; +import org.eclipse.debug.core.model.IBreakpoint; +import org.eclipse.debug.internal.ui.breakpoints.provisional.IBreakpointOrganizer; +import org.eclipse.debug.internal.ui.breakpoints.provisional.IBreakpointUIConstants; +import org.eclipse.debug.internal.ui.breakpoints.provisional.OtherBreakpointCategory; +import org.eclipse.debug.internal.ui.elements.adapters.DefaultBreakpointsViewInput; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IColumnPresentation; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IModelDelta; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IPresentationContext; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IViewerInputUpdate; +import org.eclipse.debug.ui.DebugUITools; +import org.eclipse.debug.ui.IBreakpointOrganizerDelegate; +import org.eclipse.debug.ui.contexts.DebugContextEvent; +import org.eclipse.debug.ui.contexts.IDebugContextListener; +import org.eclipse.jface.util.IPropertyChangeListener; +import org.eclipse.jface.util.PropertyChangeEvent; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.jface.viewers.TreePath; +import org.eclipse.ui.IWorkbenchWindow; + +/** + * The expression provider is used to populate the contents of the expressions + * view. The node hierarchy in this view is a little different than in a typical + * provider: the expression manager node should be registered as the single child + * of the root node and no nodes should be registered as children of expression node. + * Instead the top level expression nodes should be registered with a call to + * {@link #setExpressionNodes(IExpressionVMNode[])}. And each expression node can + * have its own sub-hierarchy of elements as needed. However all nodes configured + * with this provider (with the exception of the root and the expression manager) + * should implement {@link IExpressionVMNode}. + * + * @since 2.1 + */ +public class BreakpointVMProvider extends AbstractVMProvider +{ + private IPropertyChangeListener fPresentationContextListener = new IPropertyChangeListener() { + public void propertyChange(PropertyChangeEvent event) { + handleEventInExecThread(event); + } + }; + + private IBreakpointsListener fBreakpointsListener = new IBreakpointsListener() { + public void breakpointsRemoved(IBreakpoint[] breakpoints, IMarkerDelta[] deltas) { + handleEventInExecThread(new BreakpointsChangedEvent(BreakpointsChangedEvent.Type.REMOVED, breakpoints)); + } + + public void breakpointsChanged(IBreakpoint[] breakpoints, IMarkerDelta[] deltas) { + handleEventInExecThread(new BreakpointsChangedEvent(BreakpointsChangedEvent.Type.CHANGED, breakpoints)); + } + + public void breakpointsAdded(IBreakpoint[] breakpoints) { + handleEventInExecThread(new BreakpointsChangedEvent(BreakpointsChangedEvent.Type.ADDED, breakpoints)); + } + + }; + + private IDebugContextListener fDebugContextListener = new IDebugContextListener() { + public void debugContextChanged(final DebugContextEvent event) { + handleEventInExecThread(event); + } + }; + + private class ContainerBreakpointsCache extends DataCache> { + + private BreakpointOrganizerVMNode fOrganizerVMNode; + private TreePath fParentPath; + + public ContainerBreakpointsCache(BreakpointOrganizerVMNode organizerVMNode, TreePath parentPath) { + super(getExecutor()); + fOrganizerVMNode = organizerVMNode; + fParentPath = parentPath; + } + + @Override + protected void retrieve(final DataRequestMonitor> rm) { + getNestingCategoryBreakpoints( + fParentPath, + new DataRequestMonitor(getExecutor(), rm) { + @SuppressWarnings({ "cast", "unchecked" }) + @Override + protected void handleSuccess() { + Map> bpsLists = new HashMap>(); + for (IBreakpoint bp : getData()) { + IAdaptable[] bpCategories = fOrganizerVMNode.getOrganizer().getCategories(bp); + if (bpCategories == null || bpCategories.length == 0) { + bpCategories = OtherBreakpointCategory.getCategories(fOrganizerVMNode.getOrganizer()); + } + + for (IAdaptable category : bpCategories) { + List categoryBPs = bpsLists.get(category); + if (categoryBPs == null) { + categoryBPs = new ArrayList(); + bpsLists.put(category, categoryBPs); + } + categoryBPs.add(bp); + } + } + + // Only show the empty containers for the top-level node. + if (fParentPath.getSegmentCount() == 0) { + final IAdaptable[] independentCategories = fOrganizerVMNode.getOrganizer().getCategories(); + if (independentCategories != null) { + for (IAdaptable category : independentCategories) { + if (!bpsLists.containsKey(category)) { + bpsLists.put(category, (List)Collections.EMPTY_LIST); + } + } + } + } + + List vmcs = new ArrayList(bpsLists.size()); + for (Map.Entry> entry : bpsLists.entrySet()) { + List bpsList = entry.getValue(); + IBreakpoint[] bpsArray = bpsList.toArray(new IBreakpoint[bpsList.size()]); + + vmcs.add(createBreakpointOrganizerVMContext(fOrganizerVMNode, entry.getKey(), bpsArray)); + } + Comparator comparator = (Comparator)getPresentationContext().getProperty( + IBreakpointUIConstants.PROP_BREAKPOINTS_ELEMENT_COMPARATOR); + if (comparator != null) { + Collections.sort(vmcs, comparator); + } + + rm.setData(vmcs); + rm.done(); + } + }); + } + }; + + private final Map fContainerBreakpointsCacheMap = + new HashMap(); + + private DataCache fFilteredBreakpointsCache = new DataCache(getExecutor()) { + @Override + protected void retrieve(org.eclipse.cdt.dsf.concurrent.DataRequestMonitor rm) { + calcFileteredBreakpoints(rm); + } + }; + + public BreakpointVMProvider(AbstractVMAdapter adapter, IPresentationContext context) { + super(adapter, context); + + // Create the top level node which provides the anchor starting point. + // This node is referenced by the BreakpointVMInput element so it + // should not change when the view layout is updated. + setRootNode(new RootDMVMNode(this)); + // Configure the rest of the layout nodes. + configureLayout(); + + context.addPropertyChangeListener(fPresentationContextListener); + DebugPlugin.getDefault().getBreakpointManager().addBreakpointListener(fBreakpointsListener); + IWorkbenchWindow window = context.getWindow(); + if (window != null) { + DebugUITools.getDebugContextManager().getContextService(window).addDebugContextListener( + fDebugContextListener); + } + + } + + @Override + protected IVMModelProxy createModelProxyStrategy(Object rootElement) { + return new BreakpointVMModelProxyStrategy(this, rootElement); + } + + protected IVMNode createBreakpointVMNode() { + return new BreakpointVMNode(this); + } + + /** + * Configures the nodes of this provider. This method may be over-ridden by + * sub classes to create an alternate configuration in this provider. + */ + protected void configureLayout() { + IBreakpointOrganizer[] organizers = (IBreakpointOrganizer[]) + getPresentationContext().getProperty(IBreakpointUIConstants.PROP_BREAKPOINTS_ORGANIZERS); + + IVMNode parentNode = getRootVMNode(); + if (organizers != null) { + for (IBreakpointOrganizer organizer : organizers) { + IVMNode organizerNode = new BreakpointOrganizerVMNode(this, organizer); + addChildNodes(parentNode, new IVMNode[] {organizerNode}); + parentNode = organizerNode; + } + } + + IVMNode bpsNode = createBreakpointVMNode(); + addChildNodes(parentNode, new IVMNode[] {bpsNode}); + } + + + @Override + public void dispose() { + getPresentationContext().removePropertyChangeListener(fPresentationContextListener); + DebugPlugin.getDefault().getBreakpointManager().removeBreakpointListener(fBreakpointsListener); + IWorkbenchWindow window = getPresentationContext().getWindow(); + if (window != null) { + DebugUITools.getDebugContextManager().getContextService(window).removeDebugContextListener( + fDebugContextListener); + } + super.dispose(); + } + + @Override + public IColumnPresentation createColumnPresentation(IPresentationContext context, Object element) { + return null; + } + + @Override + public String getColumnPresentationId(IPresentationContext context, Object element) { + return null; + } + + @Override + public void update(IViewerInputUpdate update) { + IDMContext activeDMContext = null; + if (update.getElement() instanceof IDMVMContext) { + activeDMContext = ((IDMVMContext)update.getElement()).getDMContext(); + activeDMContext = DMContexts.getAncestorOfType(activeDMContext, IBreakpointsTargetDMContext.class); + } + if (activeDMContext != null) { + update.setInputElement(new BreakpointVMInput(getRootVMNode(), activeDMContext)); + } else { + // If no breakpoints target found in active context, delegate the breakpoint + // presentation to the default: breakpoint manager. + update.setInputElement(new DefaultBreakpointsViewInput(update.getPresentationContext())); + } + update.done(); + } + + public void getNestingCategoryBreakpoints(TreePath path, final DataRequestMonitor rm) { + BreakpointOrganizerVMContext nestingOrganizerVmc = null; + while (path.getSegmentCount() > 0) { + if (path.getLastSegment() instanceof BreakpointOrganizerVMContext) { + nestingOrganizerVmc = (BreakpointOrganizerVMContext)path.getLastSegment(); + break; + } + path = path.getParentPath(); + } + if (nestingOrganizerVmc == null) { + getFileteredBreakpoints(rm); + } else { + final BreakpointOrganizerVMContext _nestingOrganizerVmc = nestingOrganizerVmc; + getBreakpointOrganizerVMCs( + (BreakpointOrganizerVMNode)_nestingOrganizerVmc.getVMNode(), path.getParentPath(), + new DataRequestMonitor>(getExecutor(), rm) { + @Override + protected void handleSuccess() { + int newVmcIdx = getData().indexOf(_nestingOrganizerVmc); + + if (newVmcIdx >= 0) { + rm.setData(getData().get(newVmcIdx).getBreakpoints()); + } else { + rm.setStatus(new Status(IStatus.ERROR, DsfUIPlugin.PLUGIN_ID, IDsfStatusConstants.INVALID_HANDLE, "Breakpoint category not found", null)); //$NON-NLS-1$ + } + rm.done(); + } + }); + } + } + + public void getBreakpointOrganizerVMCs(BreakpointOrganizerVMNode organizerVMNode, TreePath path, + DataRequestMonitor> rm) + { + ContainerBreakpointsCache cache = fContainerBreakpointsCacheMap.get(path); + if (cache == null) { + cache = new ContainerBreakpointsCache(organizerVMNode, path); + fContainerBreakpointsCacheMap.put(path, cache); + } + + cache.request(rm); + } + + + protected BreakpointOrganizerVMContext createBreakpointOrganizerVMContext(BreakpointOrganizerVMNode node, IAdaptable category, IBreakpoint[] breakpoints) { + return new BreakpointOrganizerVMContext(node, category, breakpoints); + } + + + public void getFileteredBreakpoints(final DataRequestMonitor rm) { + fFilteredBreakpointsCache.request(rm); + } + + protected void calcFileteredBreakpoints(DataRequestMonitor rm) { + rm.setData(DebugPlugin.getDefault().getBreakpointManager().getBreakpoints()); + rm.done(); + } + + public void getBreakpointsForDebugContext(ISelection debugContext, DataRequestMonitor rm) { + rm.setStatus(new Status(IStatus.ERROR, DsfUIPlugin.PLUGIN_ID, IDsfStatusConstants.NOT_SUPPORTED, "Not supported", null)); //$NON-NLS-1$ + rm.done(); + } + + public void handleEventInExecThread(final Object event) { + getExecutor().execute(new DsfRunnable() { + public void run() { + handleEvent(event); + } + }); + } + + @Override + public void handleEvent(Object event, RequestMonitor rm) { + if (isPresentationContextEvent(event)) { + PropertyChangeEvent propertyEvent = (PropertyChangeEvent)event; + if (IBreakpointUIConstants.PROP_BREAKPOINTS_ORGANIZERS.equals(propertyEvent.getProperty())) + { + clearNodes(false); + configureLayout(); + } + } + super.handleEvent(event, rm); + } + + public static boolean isPresentationContextEvent(Object event) { + return event instanceof PropertyChangeEvent && ((PropertyChangeEvent)event).getSource() instanceof IPresentationContext; + } + + public static boolean isBreakpointOrganizerEvent(Object event) { + return event instanceof PropertyChangeEvent && ((PropertyChangeEvent)event).getSource() instanceof IBreakpointOrganizerDelegate; + } + + private static final int MODEL_DELTA_CHANGE_FLAGS = IModelDelta.STATE | IModelDelta.CONTENT | IModelDelta.ADDED | IModelDelta.REMOVED | IModelDelta.REPLACED | IModelDelta.INSERTED; + + @Override + protected void handleEvent(IVMModelProxy proxyStrategy, Object event, RequestMonitor rm) { + // Before generating a delta, flush the caches. + int deltaFlags = proxyStrategy.getEventDeltaFlags(event); + if ((deltaFlags & MODEL_DELTA_CHANGE_FLAGS) != 0) { + flushCaches(); + } + + super.handleEvent(proxyStrategy, event, rm); + } + + private void flushCaches() { + fFilteredBreakpointsCache.reset(); + for (DataCache cache : fContainerBreakpointsCacheMap.values()) { + cache.reset(); + } + fContainerBreakpointsCacheMap.clear(); + } +}