Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDarin Wright2010-05-03 16:16:03 -0400
committerDarin Wright2010-05-03 16:16:03 -0400
commita3a2d1fe06229fce36f67787c1f6fe96d9fc93cd (patch)
tree4a3239e8f3dd7f97e79413e624246e32804354b6 /org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/model
parent898af1b7329c1237c1b73f7b810c03c9a5522112 (diff)
downloadeclipse.platform.debug-a3a2d1fe06229fce36f67787c1f6fe96d9fc93cd.tar.gz
eclipse.platform.debug-a3a2d1fe06229fce36f67787c1f6fe96d9fc93cd.tar.xz
eclipse.platform.debug-a3a2d1fe06229fce36f67787c1f6fe96d9fc93cd.zip
Bug 311384 - NPE toggling breakpoints
Diffstat (limited to 'org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/model')
-rw-r--r--org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/model/elements/BreakpointManagerContentProvider.java2199
1 files changed, 1103 insertions, 1096 deletions
diff --git a/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/model/elements/BreakpointManagerContentProvider.java b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/model/elements/BreakpointManagerContentProvider.java
index d2a98f2ae..1133a43dc 100644
--- a/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/model/elements/BreakpointManagerContentProvider.java
+++ b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/model/elements/BreakpointManagerContentProvider.java
@@ -1,1096 +1,1103 @@
-/*****************************************************************
- * Copyright (c) 2009, 2010 Texas Instruments 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:
- * Patrick Chuong (Texas Instruments) - Initial API and implementation (Bug 238956)
- * IBM Corporation - ongoing enhancements and bug fixing
- * Wind River Systems - ongoing enhancements and bug fixing
- *****************************************************************/
-package org.eclipse.debug.internal.ui.model.elements;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.LinkedHashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
-import org.eclipse.core.resources.IMarkerDelta;
-import org.eclipse.core.runtime.CoreException;
-import org.eclipse.core.runtime.IProgressMonitor;
-import org.eclipse.core.runtime.IStatus;
-import org.eclipse.core.runtime.Platform;
-import org.eclipse.core.runtime.Status;
-import org.eclipse.core.runtime.jobs.ISchedulingRule;
-import org.eclipse.core.runtime.jobs.Job;
-import org.eclipse.debug.core.DebugPlugin;
-import org.eclipse.debug.core.IBreakpointManager;
-import org.eclipse.debug.core.IBreakpointsListener;
-import org.eclipse.debug.core.ILaunch;
-import org.eclipse.debug.core.model.IBreakpoint;
-import org.eclipse.debug.core.model.IDebugElement;
-import org.eclipse.debug.core.model.IDebugTarget;
-import org.eclipse.debug.core.model.IProcess;
-import org.eclipse.debug.core.model.IStackFrame;
-import org.eclipse.debug.core.model.IThread;
-import org.eclipse.debug.internal.ui.DebugUIPlugin;
-import org.eclipse.debug.internal.ui.breakpoints.provisional.IBreakpointOrganizer;
-import org.eclipse.debug.internal.ui.breakpoints.provisional.IBreakpointUIConstants;
-import org.eclipse.debug.internal.ui.elements.adapters.DefaultBreakpointsViewInput;
-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.IViewerUpdate;
-import org.eclipse.debug.internal.ui.viewers.model.provisional.ModelDelta;
-import org.eclipse.debug.internal.ui.viewers.update.BreakpointManagerProxy;
-import org.eclipse.debug.internal.ui.views.breakpoints.BreakpointContainer;
-import org.eclipse.debug.internal.ui.views.breakpoints.ElementComparator;
-import org.eclipse.debug.ui.DebugUITools;
-import org.eclipse.debug.ui.IDebugUIConstants;
-import org.eclipse.debug.ui.contexts.DebugContextEvent;
-import org.eclipse.debug.ui.contexts.IDebugContextListener;
-import org.eclipse.debug.ui.contexts.IDebugContextService;
-import org.eclipse.jface.util.IPropertyChangeListener;
-import org.eclipse.jface.util.PropertyChangeEvent;
-import org.eclipse.jface.viewers.ISelection;
-import org.eclipse.jface.viewers.IStructuredSelection;
-import org.eclipse.jface.viewers.StructuredSelection;
-import org.eclipse.ui.IWorkbenchWindow;
-
-/**
- * This class provides breakpoint content for the breakpoint manager.
- *
- * @since 3.6
- */
-public class BreakpointManagerContentProvider extends ElementContentProvider
- implements IBreakpointsListener {
-
- /**
- * Breakpoint input data. Contains all input specific data.
- *
- * @since 3.6
- */
- private class InputData {
- /**
- * Breakpoint manager input
- */
- final private DefaultBreakpointsViewInput fInput;
-
- /**
- * Model proxy of the input
- */
- final private List/*<AbstractModelProxy>*/ fProxies = new ArrayList(1);
-
- /**
- * Element comparator, use to compare the ordering of elements for the model
- * <br/> Note: We assume that the comparator does not change.
- */
- private ElementComparator fComparator;
-
- /**
- * The breakpoint root container.<br/>
- * Note: The final qualifier guarantees that fContainer will be
- * initialized before the class is accessed on other threads.
- */
- final private BreakpointContainer fContainer;
-
- /**
- * Known current breakpoint organizers.
- */
- private IBreakpointOrganizer[] fOrganizers;
-
- private IStructuredSelection fDebugContext = StructuredSelection.EMPTY;
-
- private IPropertyChangeListener fOrganizersListener = new IPropertyChangeListener() {
- public void propertyChange(PropertyChangeEvent event) {
- // For any property changes in breakpiont organizers, refresh the containers.
- updateContainers();
- }
- };
-
- private IPropertyChangeListener fPresentationContextListener = new IPropertyChangeListener() {
- public void propertyChange(PropertyChangeEvent event) {
- presentationPropertyChanged(event);
- }
- };
-
- private IDebugContextListener fDebugContextListener = new IDebugContextListener() {
- public void debugContextChanged(DebugContextEvent event) {
- InputData.this.debugContextChanged(event);
- }
- };
-
- /**
- * Constructor
- *
- * @param input the breakpoint manager input
- * @param proxy the model proxy
- * @param filter the debug context selection
- * @param comparator the element comparator
- */
- InputData(DefaultBreakpointsViewInput input) {
- fInput = input;
- fComparator = (ElementComparator)
- input.getContext().getProperty(IBreakpointUIConstants.PROP_BREAKPOINTS_ELEMENT_COMPARATOR);
-
- fOrganizers = (IBreakpointOrganizer[])
- input.getContext().getProperty(IBreakpointUIConstants.PROP_BREAKPOINTS_ORGANIZERS);
-
- // Create the initial container.
- ModelDelta initialDelta = new ModelDelta(fInput, 0, IModelDelta.NO_CHANGE, -1);
- IBreakpoint[] breakpoints = filterBreakpoints(
- fInput, getSelectionFilter(fInput, getDebugContext()), fBpManager.getBreakpoints());
- fContainer = createRootContainer(initialDelta, fInput, fOrganizers, breakpoints);
-
- registerOrganizersListener(null, fOrganizers);
- input.getContext().addPropertyChangeListener(fPresentationContextListener);
-
- IWorkbenchWindow window = fInput.getContext().getWindow();
- if (window != null) {
- IDebugContextService debugContextService = DebugUITools.getDebugContextManager().getContextService(window);
- ISelection debugContext = debugContextService.getActiveContext();
- if (debugContext instanceof IStructuredSelection) {
- synchronized(this) {
- fDebugContext = (IStructuredSelection)debugContext;
- }
- }
- debugContextService.addDebugContextListener(fDebugContextListener);
- }
- }
-
- void dispose() {
- // Unregister listener to breakpoint organizers.
- IBreakpointOrganizer[] organizers;
- synchronized(this) {
- organizers = fOrganizers;
- fOrganizers = null;
- }
- registerOrganizersListener(organizers, null);
-
- // Unregister listener to presentation context.
- fInput.getContext().removePropertyChangeListener(fPresentationContextListener);
-
- // Unregister listener to debug context in window.
- IWorkbenchWindow window = fInput.getContext().getWindow();
- if (window != null) {
- IDebugContextService debugContextService = DebugUITools.getDebugContextManager().getContextService(window);
- debugContextService.removeDebugContextListener(fDebugContextListener);
- }
-
- }
-
- void proxyInstalled(BreakpointManagerProxy proxy) {
- ModelDelta rootDelta = null;
- synchronized(this) {
- fProxies.add(proxy);
-
- // Generate an install delta
-
- rootDelta = new ModelDelta(fInput, 0, IModelDelta.NO_CHANGE, -1);
- buildInstallDelta(rootDelta, fContainer);
-
- if (DEBUG_BREAKPOINT_DELTAS) {
- System.out.println("PROXY INSTALLED (" + proxy + ")\n"); //$NON-NLS-1$ //$NON-NLS-2$
- }
-
- proxy.postModelChanged(rootDelta, false);
- }
- }
-
- synchronized void proxyDisposed(BreakpointManagerProxy proxy) {
- fProxies.remove(proxy);
- if (DEBUG_BREAKPOINT_DELTAS) {
- System.out.println("PROXY DISPOSED (" + proxy + ")\n"); //$NON-NLS-1$ //$NON-NLS-2$
- }
- }
-
- synchronized BreakpointManagerProxy[] getProxies() {
- return (BreakpointManagerProxy[])fProxies.toArray(new BreakpointManagerProxy[fProxies.size()]);
- }
-
- /**
- * Change the breakpoint organizers for the root container.
- *
- * @param organizers the new organizers.
- */
- void setOrganizers(IBreakpointOrganizer[] organizers) {
- IBreakpointOrganizer[] oldOrganizers = null;
- synchronized(this) {
- oldOrganizers = fOrganizers;
- fOrganizers = organizers;
- }
- registerOrganizersListener(oldOrganizers, organizers);
- updateContainers();
- }
-
- private void registerOrganizersListener(IBreakpointOrganizer[] oldOrganizers, IBreakpointOrganizer[] newOrganizers) {
- if (oldOrganizers != null) {
- for (int i = 0; i < oldOrganizers.length; i++) {
- oldOrganizers[i].removePropertyChangeListener(fOrganizersListener);
- }
- }
- if (newOrganizers != null) {
- for (int i = 0; i < newOrganizers.length; i++) {
- newOrganizers[i].addPropertyChangeListener(fOrganizersListener);
- }
- }
- }
-
- void updateContainers() {
- IBreakpoint[] breakpoints = filterBreakpoints(
- fInput, getSelectionFilter(fInput, getDebugContext()), fBpManager.getBreakpoints());
-
- synchronized(this) {
- ModelDelta delta = new ModelDelta(fInput, IModelDelta.NO_CHANGE);
- // create a reference container, use for deleting elements and adding elements
- ModelDelta dummyDelta = new ModelDelta(null, IModelDelta.NO_CHANGE);
- BreakpointContainer refContainer = createRootContainer(dummyDelta, fInput, fOrganizers, breakpoints);
-
- // delete the removed elements
- deleteRemovedElements(fContainer, refContainer, delta);
-
- // adjust the old organizer with the reference organizer
- BreakpointContainer.copyOrganizers(fContainer, refContainer);
-
- // insert the added elements
- IBreakpoint newBreakpoint = insertAddedElements(fContainer, refContainer, delta);
- delta.setChildCount(fContainer.getChildren().length);
-
- // select the new breakpoint
- if (newBreakpoint != null) {
- appendModelDeltaToElement(delta, newBreakpoint, IModelDelta.SELECT);
- }
- if (DEBUG_BREAKPOINT_DELTAS) {
- System.out.println("POST BREAKPOINT DELTA (setOrganizers)\n"); //$NON-NLS-1$
- }
- postModelChanged(delta, false);
- }
- }
-
- private synchronized IStructuredSelection getDebugContext() {
- return fDebugContext;
- }
-
- /**
- * Handles the property changed events in presentation contexts.
- * Sub-classes may override to perform additional handling.
- *
- * @param presentation Presentation context that changed.
- */
- private void presentationPropertyChanged(PropertyChangeEvent event) {
- if (IPresentationContext.PROPERTY_DISPOSED.equals(event.getProperty())) {
- contextDisposed(fInput.getContext());
- }
- if (IBreakpointUIConstants.PROP_BREAKPOINTS_ORGANIZERS.equals(event.getProperty())) {
- IBreakpointOrganizer[] organizers = (IBreakpointOrganizer[])event.getNewValue();
- setOrganizers(organizers);
- }
- else if ( IBreakpointUIConstants.PROP_BREAKPOINTS_FILTER_SELECTION.equals(event.getProperty()) )
- {
- IStructuredSelection selection = null;
-
- if (Boolean.TRUE.equals(event.getNewValue()) ) {
- selection = getDebugContext();
- }
- setFilterSelection(selection);
- }
- else if ( IBreakpointUIConstants.PROP_BREAKPOINTS_TRACK_SELECTION.equals(event.getProperty()) )
- {
- IStructuredSelection selection = null;
-
- if (Boolean.TRUE.equals(event.getNewValue()) ) {
- selection = getDebugContext();
- }
- trackSelection(selection);
- }
- }
-
- private void debugContextChanged(DebugContextEvent event) {
- IStructuredSelection newContext;
- if (event.getContext() instanceof IStructuredSelection) {
- newContext = (IStructuredSelection)event.getContext();
- } else {
- newContext = StructuredSelection.EMPTY;
- }
-
- synchronized(this) {
- fDebugContext = newContext;
- }
-
- if (Boolean.TRUE.equals(fInput.getContext().getProperty(IBreakpointUIConstants.PROP_BREAKPOINTS_FILTER_SELECTION)) ) {
- setFilterSelection(newContext);
- }
-
- if (Boolean.TRUE.equals(fInput.getContext().getProperty(IBreakpointUIConstants.PROP_BREAKPOINTS_TRACK_SELECTION)) ) {
- trackSelection(newContext);
- }
- }
-
-
- private void setFilterSelection(IStructuredSelection ss) {
- ModelDelta delta = new ModelDelta(fInput, IModelDelta.NO_CHANGE);
- boolean changed = false;
-
- // calculate supported breakpoints outside of the synchronized section.
- IBreakpoint[] allBreakpoints = fBpManager.getBreakpoints();
- boolean[] supportedBreakpoints = new boolean[allBreakpoints.length];
- for (int i = 0; i < allBreakpoints.length; ++i) {
- supportedBreakpoints[i] = supportsBreakpoint(ss, allBreakpoints[i]);
- }
-
- synchronized(this) {
- Set existingBreakpoints = new HashSet(Arrays.asList(fContainer.getBreakpoints()));
-
- for (int i = 0; i < allBreakpoints.length; ++i) {
- boolean contain = existingBreakpoints.contains(allBreakpoints[i]);
-
- if (supportedBreakpoints[i]) {
- if (!contain) {
- fContainer.addBreakpoint(allBreakpoints[i], delta);
- changed = true;
- }
- } else {
- if (contain) {
- fContainer.removeBreakpoint(allBreakpoints[i], delta);
- changed = true;
- }
-
- }
-
- }
-
- if (changed) {
- if (DEBUG_BREAKPOINT_DELTAS) {
- System.out.println("POST BREAKPOINT DELTA (setFilterSelection)\n"); //$NON-NLS-1$
- }
- postModelChanged(delta, false);
- }
- }
- }
-
-
- private void trackSelection(IStructuredSelection selection) {
- if (selection == null || selection.size() != 1) {
- return;
- }
-
- Iterator iter = selection.iterator();
- Object firstElement = iter.next();
- if (firstElement == null || iter.hasNext()) {
- return;
- }
- IThread thread = null;
- if (firstElement instanceof IStackFrame) {
- thread = ((IStackFrame) firstElement).getThread();
- } else if (firstElement instanceof IThread) {
- thread = (IThread) firstElement;
- } else {
- return;
- }
-
- IBreakpoint[] breakpoints = thread.getBreakpoints();
- Set bpsSet = new HashSet(breakpoints.length * 4/3);
- for (int i = 0; i< breakpoints.length; i++) {
- bpsSet.add(breakpoints[i]);
- }
-
- ModelDelta delta = new ModelDelta(fInput, IModelDelta.NO_CHANGE);
- synchronized (this) {
- if (buildTrackSelectionDelta(delta, fContainer, bpsSet)) {
- if (DEBUG_BREAKPOINT_DELTAS) {
- System.out.println("POST BREAKPOINT DELTA (trackSelection)\n"); //$NON-NLS-1$
- }
- BreakpointManagerProxy[] proxies = getProxies();
- for (int i = 0; i < proxies.length; i++) {
- proxies[i].postModelChanged(delta, true);
- }
- }
- }
-
- }
-
- /**
- * Recursive function to build the model delta to select a breakpoint
- * corresponding to the active debug context selection.
- *
- * @param delta Delta node to build on
- * @param container Container element to build delta for.
- * @param breakpoints Breakpoint set to be selected.
- * @return whether we found a breakpoint to select
- */
- private boolean buildTrackSelectionDelta(ModelDelta delta, BreakpointContainer container, Set breakpoints) {
- Object[] children = container.getChildren();
- delta.setChildCount(children.length);
- for (int i = 0; i < children.length; i++) {
- ModelDelta childDelta = delta.addNode(children[i], i, IModelDelta.NO_CHANGE);
- if (children[i] instanceof BreakpointContainer) {
- BreakpointContainer childContainer = (BreakpointContainer)children[i];
- boolean containsBP = false;
- IBreakpoint[] containerBPs = childContainer.getBreakpoints();
- for (int j = 0; j < containerBPs.length; j++) {
- if (breakpoints.contains(containerBPs[j])) {
- containsBP = true;
- break;
- }
- }
- if (containsBP && buildTrackSelectionDelta(childDelta, childContainer, breakpoints) ) {
- return true;
- }
- } else if (children[i] instanceof IBreakpoint &&
- breakpoints.contains(children[i]))
- {
- childDelta.setFlags(IModelDelta.SELECT | IModelDelta.EXPAND);
- return true;
- }
- }
- return false;
- }
-
- /**
- * Helper method to add breakpoints to the given input.
- *
- * @param data the input to add the breakpoints
- * @param breakpoints the breakpoints
- */
- void breakpointsAdded(IBreakpoint[] breakpoints) {
- IBreakpoint[] filteredBreakpoints = filterBreakpoints(
- fInput, getSelectionFilter(fInput, getDebugContext()), breakpoints);
-
- synchronized (this) {
- ModelDelta delta = new ModelDelta(fInput, 0, IModelDelta.NO_CHANGE, -1);
- for (int i = 0; i < filteredBreakpoints.length; ++i) {
- fContainer.addBreakpoint(filteredBreakpoints[i], delta);
- }
- delta.setChildCount(fContainer.getChildren().length);
-
- // select the breakpoint
- if (filteredBreakpoints.length > 0) {
- appendModelDeltaToElement(delta, filteredBreakpoints[0], IModelDelta.SELECT);
- }
-
- if (DEBUG_BREAKPOINT_DELTAS) {
- System.out.println("POST BREAKPOINT DELTA (breakpointsAddedInput)\n"); //$NON-NLS-1$
- }
- postModelChanged(delta, false);
- }
- }
-
- /**
- * Helper method to remove breakpoints from a given input.
- *
- * @param data the input to add the breakpoints
- * @param breakpoints the breakpoints
- */
- void breakpointsRemoved(IBreakpoint[] breakpoints) {
- IBreakpoint[] filteredBreakpoints = filterBreakpoints(
- fInput, getSelectionFilter(fInput, getDebugContext()), breakpoints);
-
- synchronized (this) {
- ModelDelta delta = new ModelDelta(fInput, IModelDelta.NO_CHANGE);
- for (int i = 0; i < filteredBreakpoints.length; ++i) {
- fContainer.removeBreakpoint(filteredBreakpoints[i], delta);
- }
-
- if (DEBUG_BREAKPOINT_DELTAS) {
- System.out.println("POST BREAKPOINT DELTA (breakpointsRemovedInput)\n"); //$NON-NLS-1$
- }
- postModelChanged(delta, false);
- }
- }
-
- void breakpointsChanged(IBreakpoint[] breakpoints) {
-
-
- IBreakpoint[] filteredBreakpoints = filterBreakpoints(
- fInput, getSelectionFilter(fInput, getDebugContext()), breakpoints);
-
- synchronized (this) {
- ModelDelta delta = new ModelDelta(fInput, IModelDelta.NO_CHANGE);
-
- // If the change caused a breakpoint to be added (installed) or remove (un-installed) update accordingly.
- List removed = new ArrayList();
- List added = new ArrayList();
- List filteredAsList = Arrays.asList(filteredBreakpoints);
- for (int i = 0; i < breakpoints.length; i++) {
- IBreakpoint bp = breakpoints[i];
- boolean oldContainedBp = fContainer.contains(bp);
- boolean newContained = filteredAsList.contains(bp);
- if (oldContainedBp && !newContained) {
- removed.add(bp);
- } else if (!oldContainedBp && newContained) {
- added.add(bp);
- }
- }
- if (!added.isEmpty()) {
- breakpointsAdded((IBreakpoint[]) added.toArray(new IBreakpoint[added.size()]));
- }
- if (!removed.isEmpty()) {
- breakpointsRemoved((IBreakpoint[]) removed.toArray(new IBreakpoint[removed.size()]));
- }
- for (int i = 0; i < filteredBreakpoints.length; ++i)
- appendModelDelta(fContainer, delta, IModelDelta.STATE | IModelDelta.CONTENT, filteredBreakpoints[i]); // content flag triggers detail refresh
-
- if (DEBUG_BREAKPOINT_DELTAS) {
- System.out.println("POST BREAKPOINT DELTA (breakpointsChanged)\n"); //$NON-NLS-1$
- }
- postModelChanged(delta, false);
- }
- }
-
-
- /**
- * Recursive function to build the model delta to install breakpoint
- * model proxies for all breakpoints and breakpoint containers.
- *
- * @param delta Delta node to build on
- * @param container Container element to build delta for.
- */
- private void buildInstallDelta(ModelDelta delta, BreakpointContainer container) {
- Object[] children = container.getChildren();
- delta.setChildCount(children.length);
- for (int i = 0; i < children.length; i++) {
- ModelDelta childDelta = delta.addNode(children[i], i, IModelDelta.NO_CHANGE);
- if (children[i] instanceof BreakpointContainer) {
- childDelta.setFlags(IModelDelta.INSTALL);
- buildInstallDelta(childDelta, (BreakpointContainer)children[i]);
- } else if (children[i] instanceof IBreakpoint) {
- childDelta.setFlags(IModelDelta.INSTALL);
- }
- }
- }
-
-
- /**
- * Insert elements from the reference container to an existing container.
- *
- * @param container the existing container to insert the new elements.
- * @param refContainer the reference container to compare elements that are added.
- * @param containerDelta the delta of the existing container.
- */
- private IBreakpoint insertAddedElements(BreakpointContainer container, BreakpointContainer refContainer, ModelDelta containerDelta) {
- IBreakpoint newBreakpoint = null;
-
- Object[] children = container.getChildren();
- Object[] refChildren = refContainer.getChildren();
-
-
- for (int i = 0; i < refChildren.length; ++i) {
- Object element = getElement(children, refChildren[i]);
-
- // if a child of refContainer doesn't exist in container, than insert it to container
- // - if the reference child is a container, than copy the reference child container to container
- // - otherwise (Breakpoint), add the breakpoint to container
- if (element == null) {
- if (refChildren[i] instanceof BreakpointContainer) {
- BreakpointContainer.addChildContainer(container, (BreakpointContainer) refChildren[i], containerDelta);
- } else {
- BreakpointContainer.addBreakpoint(container, (IBreakpoint) refChildren[i], containerDelta);
- if (newBreakpoint == null)
- newBreakpoint = (IBreakpoint) refChildren[i];
- }
-
- // if a child exist in container, than recursively search into container. And also update the organizer of
- // of container to the one in the refContainer's child.
- } else if (element instanceof BreakpointContainer) {
- int index = Arrays.asList(children).indexOf(element);
- ModelDelta childDelta = containerDelta.addNode(element, index, IModelDelta.STATE, -1);
- BreakpointContainer.copyOrganizers((BreakpointContainer) element, (BreakpointContainer) refChildren[i]);
- newBreakpoint = insertAddedElements((BreakpointContainer) element, (BreakpointContainer) refChildren[i], childDelta);
- childDelta.setChildCount(((BreakpointContainer) element).getChildren().length);
- }
- }
-
- return newBreakpoint;
- }
-
- /**
- * Delete elements from existing container that doesn't exist in the reference container.
- *
- * @param container the existing container to delete the removed elements.
- * @param refContainer the reference container to compare elements that are removed.
- * @param containerDelta the delta of the existing container.
- */
- private void deleteRemovedElements(BreakpointContainer container, BreakpointContainer refContainer, ModelDelta containerDelta) {
- Object[] children = container.getChildren();
- Object[] refChildren = refContainer.getChildren();
-
- // if a child of container doesn't exist in refContainer, than remove it from container
- for (int i = 0; i < children.length; ++i) {
- Object element = getElement(refChildren, children[i]);
-
- if (element == null) {
- if (children[i] instanceof BreakpointContainer) {
- BreakpointContainer.removeAll((BreakpointContainer) children[i], containerDelta);
- } else {
- BreakpointContainer.removeBreakpoint(container, (IBreakpoint) children[i], containerDelta);
- }
- } else if (element instanceof BreakpointContainer){
-
- ModelDelta childDelta = containerDelta.addNode(children[i], IModelDelta.STATE);
- deleteRemovedElements((BreakpointContainer) children[i], (BreakpointContainer) element, childDelta);
- }
- }
- }
-
- /**
- * Get the element that is in the collection.
- *
- * @param collection the collection of elements.
- * @param element the element to search.
- * @return if element exist in collection, than it is returned, otherwise <code>null</code> is returned.
- * @see insertAddedElements
- * @see deleteRemovedElements
- */
- private Object getElement(Object[] collection, Object element) {
- for (int i = 0; i < collection.length; ++i)
- if (collection[i] instanceof BreakpointContainer && element instanceof BreakpointContainer) {
- if (collection[i].equals(element))
- return collection[i];
- } else {
- if (collection[i].equals(element))
- return collection[i];
- }
- return null;
- }
-
- /**
- * Create a root container.
- *
- * @param rootDelta the root delta.
- * @param input the view input.
- * @param organizers the breakpoint organizers.
- * @param oldContainer the old container, use to determine whether a new breakpoint should be expanded.
- * @param the breakpoint manager.
- */
- private BreakpointContainer createRootContainer(
- ModelDelta rootDelta, DefaultBreakpointsViewInput input,
- IBreakpointOrganizer[] organizers, IBreakpoint[] breakpoints)
- {
-
- BreakpointContainer container = new BreakpointContainer(organizers, fComparator);
- container.initDefaultContainers(rootDelta);
-
- for (int i = 0; i < breakpoints.length; ++i) {
- container.addBreakpoint(breakpoints[i], rootDelta);
- }
-
- return container;
- }
-
- /**
- * Fire model change event for the input.
- *
- * @param input the input.
- * @param delta the model delta.
- * @param debugReason the debug string.
- */
- synchronized private void postModelChanged(final IModelDelta delta, boolean select) {
- for (int i = 0; fProxies != null && i < fProxies.size(); i++) {
- ((BreakpointManagerProxy)fProxies.get(i)).postModelChanged(delta, select);
- }
- }
-
-
- }
-
- private class InputDataMap extends LinkedHashMap {
- private static final long serialVersionUID = 1L;
-
- public InputDataMap() {
- super(1, (float)0.75, true);
- }
-
- protected boolean removeEldestEntry(java.util.Map.Entry arg0) {
- InputData data = (InputData)arg0.getValue();
- if (size() > getMaxInputsCache() && data.fProxies.isEmpty()) {
- data.dispose();
- return true;
- }
- return false;
- }
- }
-
- /**
- * Scheduling rule to make sure that breakpoint manager listener updates
- * are process serially.
- */
- private ISchedulingRule fBreakpointsListenerSchedulingRule = new ISchedulingRule() {
-
- public boolean isConflicting(ISchedulingRule rule) {
- return rule == this;
- }
-
- public boolean contains(ISchedulingRule rule) {
- return rule == this;
- }
- };
-
- // debug flags
- public static boolean DEBUG_BREAKPOINT_DELTAS = false;
-
- static {
- DEBUG_BREAKPOINT_DELTAS = DebugUIPlugin.DEBUG && "true".equals( //$NON-NLS-1$
- Platform.getDebugOption("org.eclipse.debug.ui/debug/viewers/breakpointDeltas")); //$NON-NLS-1$
- }
-
- /**
- * A map of input to info data cache
- */
- final private Map fInputToData = Collections.synchronizedMap(new InputDataMap());
-
- /**
- * Flag indicating whether the content provider is currently a breakpoints listener.
- */
- private boolean fIsBreakpointListener = false;
-
- /**
- * The breakpoint manager.
- */
- final private IBreakpointManager fBpManager = DebugPlugin.getDefault().getBreakpointManager();
-
- /**
- * Sub-classes may override this method to filter the breakpoints.
- *
- * @param input the breakpoint manager input.
- * @param breakpoints the list of breakpoint to filter.
- * @return the filtered list of breakpoint based on the input.
- */
- protected IBreakpoint[] filterBreakpoints(DefaultBreakpointsViewInput input, IStructuredSelection selectionFilter, IBreakpoint[] breakpoints) {
- if (selectionFilter != null && !selectionFilter.isEmpty()) {
- List targets = getDebugTargets(selectionFilter);
- ArrayList retVal = new ArrayList();
- if (targets != null) {
- for (int i = 0; i < breakpoints.length; ++i) {
- if (supportsBreakpoint(targets, breakpoints[i]))
- retVal.add(breakpoints[i]);
- }
- }
- return (IBreakpoint[]) retVal.toArray(new IBreakpoint[retVal.size()]);
- } else {
- return breakpoints;
- }
- }
-
- /**
- * Sub-classes may override this to determine whether the breakpoint is supported by the selection.
- *
- * @param ss the selection of the debug elements.
- * @param breakpoint the breakpoint.
- * @return true if supported.
- */
- protected boolean supportsBreakpoint(IStructuredSelection ss, IBreakpoint breakpoint) {
- return supportsBreakpoint(getDebugTargets(ss), breakpoint);
- }
-
- /**
- * Returns true if the breakpoint contains in one of the targets.
- *
- * @param targets a list of <code>IDebugTarget</code> objects.
- * @param breakpoint the breakpoint.
- * @return true if breakpoint contains in the list of targets.
- */
- protected boolean supportsBreakpoint(List targets, IBreakpoint breakpoint) {
- boolean exist = targets.size() == 0 ? true : false;
- for (int i = 0; !exist && i < targets.size(); ++i) {
- IDebugTarget target = (IDebugTarget) targets.get(i);
- exist |= target.supportsBreakpoint(breakpoint);
- }
- return exist;
- }
-
- /**
- * Returns the list of IDebugTarget for the selection.
- *
- * @param ss the selection.
- * @return list of IDebugTarget object.
- */
- protected List getDebugTargets(IStructuredSelection ss) {
- List debugTargets = new ArrayList(2);
- if (ss != null) {
- Iterator i = ss.iterator();
- while (i.hasNext()) {
- Object next = i.next();
- if (next instanceof IDebugElement) {
- debugTargets.add(((IDebugElement)next).getDebugTarget());
- } else if (next instanceof ILaunch) {
- IDebugTarget[] targets = ((ILaunch)next).getDebugTargets();
- for (int j = 0; j < targets.length; j++) {
- debugTargets.add(targets[j]);
- }
- } else if (next instanceof IProcess) {
- IDebugTarget target = (IDebugTarget)((IProcess)next).getAdapter(IDebugTarget.class);
- if (target != null) {
- debugTargets.add(target);
- }
- }
- }
- }
- return debugTargets;
- }
-
-
- /**
- * Maximum number of breakpoint manager input objects that this provider
- * will cache data for. This method is called once upon class creation
- * when setting up the data cache. Sub-classes may override to provide
- * a custom setting.
- *
- * @return Maximum data cache size
- */
- protected int getMaxInputsCache() {
- return 2;
- }
-
- /**
- * Handles the event when a presentation context is dispoed.
- * Sub-classes may override to perform additional cleanup.
- *
- * @param context Presetnation context that was disposed.
- */
- protected void contextDisposed(IPresentationContext context) {
- List removed = new ArrayList(1);
- synchronized (fInputToData) {
- for (Iterator itr = fInputToData.entrySet().iterator(); itr.hasNext();) {
- Map.Entry entry = (Map.Entry)itr.next();
- IPresentationContext entryContext = ((DefaultBreakpointsViewInput)entry.getKey()).getContext();
- if (context.equals(entryContext)) {
- removed.add(entry.getValue());
- itr.remove();
- }
- }
- }
-
- // Dispose the removed input datas
- for (int i = 0; i < removed.size(); i++) {
- ((InputData)removed.get(i)).dispose();
- }
- }
-
- /**
- * Register the breakpoint manager input with this content provider.
- *
- * @param input the breakpoint manager input to register.
- * @param proxy the model proxy of the input.
- * @param organizers the breakpoint organizer, can be <code>null</code>.
- * @param selectionFilter the selection filter, can be <code>null</code>.
- * @param comparator the element comparator.
- */
- public void registerModelProxy(DefaultBreakpointsViewInput input, BreakpointManagerProxy proxy) {
- synchronized(this) {
- if (!fIsBreakpointListener) {
- fBpManager.addBreakpointListener(this);
- fIsBreakpointListener = true;
- }
- }
- InputData inputData = getInputData(input);
- if (inputData != null) {
- inputData.proxyInstalled(proxy);
- }
- }
-
- /**
- * Unregister the breakpoint manager input with this content provider.
- *
- * @param input the breakpoint manager input to unregister.
- */
- public void unregisterModelProxy(DefaultBreakpointsViewInput input, BreakpointManagerProxy proxy) {
- InputData inputData = (InputData)fInputToData.get(input);
- if (inputData != null) {
- inputData.proxyDisposed(proxy);
-
- if (fInputToData.isEmpty()) {
- synchronized(this) {
- if (fIsBreakpointListener) {
- fBpManager.removeBreakpointListener(this);
- fIsBreakpointListener = false;
- }
- }
- }
- }
- }
-
- private InputData getInputData(DefaultBreakpointsViewInput input) {
- if (Boolean.TRUE.equals(input.getContext().getProperty(IPresentationContext.PROPERTY_DISPOSED)) ) {
- return null;
- }
-
- InputData data = null;
- synchronized (fInputToData) {
- data = (InputData)fInputToData.get(input);
- if (data == null) {
- data = new InputData(input);
- fInputToData.put(input, data);
- }
- }
- return data;
- }
-
- /**
- * Returns the selection filter for the input.
- *
- * @param input the selection.
- */
- protected IStructuredSelection getSelectionFilter(Object input, IStructuredSelection debugContext) {
- if (input instanceof DefaultBreakpointsViewInput) {
- IPresentationContext presentation = ((DefaultBreakpointsViewInput)input).getContext();
- if ( Boolean.TRUE.equals(presentation.getProperty(IBreakpointUIConstants.PROP_BREAKPOINTS_FILTER_SELECTION)) ) {
- return debugContext;
- }
- }
- return null;
- }
-
- /* (non-Javadoc)
- * @see org.eclipse.debug.internal.ui.model.elements.ElementContentProvider#supportsContextId(java.lang.String)
- */
- protected boolean supportsContextId(String id) {
- return id.equals(IDebugUIConstants.ID_BREAKPOINT_VIEW);
- }
-
- /* (non-Javadoc)
- * @see org.eclipse.debug.internal.ui.model.elements.ElementContentProvider#getChildCount(java.lang.Object, org.eclipse.debug.internal.ui.viewers.model.provisional.IPresentationContext, org.eclipse.debug.internal.ui.viewers.model.provisional.IViewerUpdate)
- */
- protected int getChildCount(Object element, IPresentationContext context, IViewerUpdate monitor) throws CoreException {
- Object input = monitor.getViewerInput();
- if (input instanceof DefaultBreakpointsViewInput) {
- DefaultBreakpointsViewInput bpManagerInput = (DefaultBreakpointsViewInput)input;
- InputData inputData = getInputData(bpManagerInput);
- if (inputData != null) {
- return inputData.fContainer.getChildren().length;
- }
- }
- return 0;
- }
-
- /* (non-Javadoc)
- * @see org.eclipse.debug.internal.ui.model.elements.ElementContentProvider#getChildren(java.lang.Object, int, int, org.eclipse.debug.internal.ui.viewers.model.provisional.IPresentationContext, org.eclipse.debug.internal.ui.viewers.model.provisional.IViewerUpdate)
- */
- protected Object[] getChildren(Object parent, int index, int length, IPresentationContext context, IViewerUpdate monitor) throws CoreException {
- Object input = monitor.getViewerInput();
- if (input instanceof DefaultBreakpointsViewInput) {
- DefaultBreakpointsViewInput bpManagerInput = (DefaultBreakpointsViewInput)input;
- InputData inputData = getInputData(bpManagerInput);
- if (inputData != null) {
- Object[] children = inputData.fContainer.getChildren();
- return getElements(children, index, length);
- }
- }
-
- return EMPTY;
- }
-
- /*
- * (non-Javadoc)
- * @see org.eclipse.debug.core.IBreakpointsListener#breakpointsAdded(org.eclipse.debug.core.model.IBreakpoint[])
- */
- public void breakpointsAdded(final IBreakpoint[] breakpoints) {
- new Job("Breakpoints View Update Job") { //$NON-NLS-1$
- {
- setSystem(true);
- setRule(fBreakpointsListenerSchedulingRule);
- }
-
- protected IStatus run(IProgressMonitor monitor) {
- InputData[] datas = (InputData[])fInputToData.values().toArray(new InputData[0]);
- for (int i = 0; i < datas.length; i++) {
- datas[i].breakpointsAdded(breakpoints);
- }
- return Status.OK_STATUS;
- }
- }.schedule();
- }
-
- /*
- * (non-Javadoc)
- * @see org.eclipse.debug.core.IBreakpointsListener#breakpointsRemoved(org.eclipse.debug.core.model.IBreakpoint[], org.eclipse.core.resources.IMarkerDelta[])
- */
- public void breakpointsRemoved(final IBreakpoint[] breakpoints, IMarkerDelta[] deltas) {
- new Job("Breakpoints View Update Job") { //$NON-NLS-1$
- {
- setSystem(true);
- setRule(fBreakpointsListenerSchedulingRule);
- }
-
- protected IStatus run(IProgressMonitor monitor) {
- InputData[] datas = (InputData[])fInputToData.values().toArray(new InputData[0]);
- for (int i = 0; i < datas.length; i++) {
- datas[i].breakpointsRemoved(breakpoints);
- }
- return Status.OK_STATUS;
- }
- }.schedule();
- }
-
- /*
- * (non-Javadoc)
- * @see org.eclipse.debug.core.IBreakpointsListener#breakpointsChanged(org.eclipse.debug.core.model.IBreakpoint[], org.eclipse.core.resources.IMarkerDelta[])
- */
- public void breakpointsChanged(final IBreakpoint[] breakpoints, IMarkerDelta[] deltas) {
- new Job("Breakpoints View Update Job") { //$NON-NLS-1$
- {
- setSystem(true);
- setRule(fBreakpointsListenerSchedulingRule);
- }
-
- protected IStatus run(IProgressMonitor monitor) {
- InputData[] datas = (InputData[])fInputToData.values().toArray(new InputData[0]);
- for (int i = 0; i < datas.length; i++) {
- datas[i].breakpointsChanged(breakpoints);
- }
- return Status.OK_STATUS;
- }
- }.schedule();
- }
- /**
- * Appends the model delta flags to child containers that contains the breakpoint.
- *
- * @param parent the parent container.
- * @param parentDelta the parent model delta.
- * @param flags the model delta flags.
- * @param breakpoint the breakpoint to search in the children containers.
- */
- private void appendModelDelta(BreakpointContainer parent, ModelDelta parentDelta, int flags, IBreakpoint breakpoint) {
- BreakpointContainer[] containers = parent.getContainers();
-
- if (parent.contains(breakpoint)) {
- if ((containers.length != 0)) {
- for (int i = 0; i < containers.length; ++i) {
- ModelDelta nodeDelta = parentDelta.addNode(containers[i], IModelDelta.STATE);
- appendModelDelta(containers[i], nodeDelta, flags, breakpoint);
- }
- } else {
- parentDelta.addNode(breakpoint, flags);
- }
- }
- }
-
- /**
- * Appends the model delta to the first found element in the model delta tree.
- *
- * @param parentDelta the parent delta
- * @param element the element to search
- * @param flags the delta flags
- */
- private void appendModelDeltaToElement(IModelDelta parentDelta, Object element, int flags) {
- if (element.equals(parentDelta.getElement())) {
- ((ModelDelta) parentDelta).setFlags(parentDelta.getFlags() | flags);
- return;
- }
-
- IModelDelta[] childDeltas = parentDelta.getChildDeltas();
- for (int i = 0; i < childDeltas.length; ++i) {
- if (element.equals(childDeltas[i].getElement())) {
- ((ModelDelta) childDeltas[i]).setFlags(childDeltas[i].getFlags() | flags);
- return;
- }
-
- appendModelDeltaToElement(childDeltas[i], element, flags);
- }
- }
-}
+/*****************************************************************
+ * Copyright (c) 2009, 2010 Texas Instruments 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:
+ * Patrick Chuong (Texas Instruments) - Initial API and implementation (Bug 238956)
+ * IBM Corporation - ongoing enhancements and bug fixing
+ * Wind River Systems - ongoing enhancements and bug fixing
+ *****************************************************************/
+package org.eclipse.debug.internal.ui.model.elements;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import org.eclipse.core.resources.IMarkerDelta;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Platform;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.core.runtime.jobs.ISchedulingRule;
+import org.eclipse.core.runtime.jobs.Job;
+import org.eclipse.debug.core.DebugPlugin;
+import org.eclipse.debug.core.IBreakpointManager;
+import org.eclipse.debug.core.IBreakpointsListener;
+import org.eclipse.debug.core.ILaunch;
+import org.eclipse.debug.core.model.IBreakpoint;
+import org.eclipse.debug.core.model.IDebugElement;
+import org.eclipse.debug.core.model.IDebugTarget;
+import org.eclipse.debug.core.model.IProcess;
+import org.eclipse.debug.core.model.IStackFrame;
+import org.eclipse.debug.core.model.IThread;
+import org.eclipse.debug.internal.ui.DebugUIPlugin;
+import org.eclipse.debug.internal.ui.breakpoints.provisional.IBreakpointOrganizer;
+import org.eclipse.debug.internal.ui.breakpoints.provisional.IBreakpointUIConstants;
+import org.eclipse.debug.internal.ui.elements.adapters.DefaultBreakpointsViewInput;
+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.IViewerUpdate;
+import org.eclipse.debug.internal.ui.viewers.model.provisional.ModelDelta;
+import org.eclipse.debug.internal.ui.viewers.update.BreakpointManagerProxy;
+import org.eclipse.debug.internal.ui.views.breakpoints.BreakpointContainer;
+import org.eclipse.debug.internal.ui.views.breakpoints.ElementComparator;
+import org.eclipse.debug.ui.DebugUITools;
+import org.eclipse.debug.ui.IDebugUIConstants;
+import org.eclipse.debug.ui.contexts.DebugContextEvent;
+import org.eclipse.debug.ui.contexts.IDebugContextListener;
+import org.eclipse.debug.ui.contexts.IDebugContextService;
+import org.eclipse.jface.util.IPropertyChangeListener;
+import org.eclipse.jface.util.PropertyChangeEvent;
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.jface.viewers.StructuredSelection;
+import org.eclipse.ui.IWorkbenchWindow;
+
+/**
+ * This class provides breakpoint content for the breakpoint manager.
+ *
+ * @since 3.6
+ */
+public class BreakpointManagerContentProvider extends ElementContentProvider
+ implements IBreakpointsListener {
+
+ /**
+ * Breakpoint input data. Contains all input specific data.
+ *
+ * @since 3.6
+ */
+ private class InputData {
+ /**
+ * Breakpoint manager input
+ */
+ final private DefaultBreakpointsViewInput fInput;
+
+ /**
+ * Model proxy of the input
+ */
+ final private List/*<AbstractModelProxy>*/ fProxies = new ArrayList(1);
+
+ /**
+ * Element comparator, use to compare the ordering of elements for the model
+ * <br/> Note: We assume that the comparator does not change.
+ */
+ private ElementComparator fComparator;
+
+ /**
+ * The breakpoint root container.<br/>
+ * Note: The final qualifier guarantees that fContainer will be
+ * initialized before the class is accessed on other threads.
+ */
+ final private BreakpointContainer fContainer;
+
+ /**
+ * Known current breakpoint organizers.
+ */
+ private IBreakpointOrganizer[] fOrganizers;
+
+ private IStructuredSelection fDebugContext = StructuredSelection.EMPTY;
+
+ private IPropertyChangeListener fOrganizersListener = new IPropertyChangeListener() {
+ public void propertyChange(PropertyChangeEvent event) {
+ // For any property changes in breakpiont organizers, refresh the containers.
+ updateContainers();
+ }
+ };
+
+ private IPropertyChangeListener fPresentationContextListener = new IPropertyChangeListener() {
+ public void propertyChange(PropertyChangeEvent event) {
+ presentationPropertyChanged(event);
+ }
+ };
+
+ private IDebugContextListener fDebugContextListener = new IDebugContextListener() {
+ public void debugContextChanged(DebugContextEvent event) {
+ InputData.this.debugContextChanged(event);
+ }
+ };
+
+ /**
+ * Constructor
+ *
+ * @param input the breakpoint manager input
+ * @param proxy the model proxy
+ * @param filter the debug context selection
+ * @param comparator the element comparator
+ */
+ InputData(DefaultBreakpointsViewInput input) {
+ fInput = input;
+ fComparator = (ElementComparator)
+ input.getContext().getProperty(IBreakpointUIConstants.PROP_BREAKPOINTS_ELEMENT_COMPARATOR);
+
+ fOrganizers = (IBreakpointOrganizer[])
+ input.getContext().getProperty(IBreakpointUIConstants.PROP_BREAKPOINTS_ORGANIZERS);
+
+ // Create the initial container.
+ ModelDelta initialDelta = new ModelDelta(fInput, 0, IModelDelta.NO_CHANGE, -1);
+ IBreakpoint[] breakpoints = filterBreakpoints(
+ fInput, getSelectionFilter(fInput, getDebugContext()), fBpManager.getBreakpoints());
+ fContainer = createRootContainer(initialDelta, fInput, fOrganizers, breakpoints);
+
+ registerOrganizersListener(null, fOrganizers);
+ input.getContext().addPropertyChangeListener(fPresentationContextListener);
+
+ IWorkbenchWindow window = fInput.getContext().getWindow();
+ if (window != null) {
+ IDebugContextService debugContextService = DebugUITools.getDebugContextManager().getContextService(window);
+ ISelection debugContext = debugContextService.getActiveContext();
+ if (debugContext instanceof IStructuredSelection) {
+ synchronized(this) {
+ fDebugContext = (IStructuredSelection)debugContext;
+ }
+ }
+ debugContextService.addDebugContextListener(fDebugContextListener);
+ }
+ }
+
+ void dispose() {
+ // Unregister listener to breakpoint organizers.
+ IBreakpointOrganizer[] organizers;
+ synchronized(this) {
+ organizers = fOrganizers;
+ fOrganizers = null;
+ }
+ registerOrganizersListener(organizers, null);
+
+ // Unregister listener to presentation context.
+ fInput.getContext().removePropertyChangeListener(fPresentationContextListener);
+
+ // Unregister listener to debug context in window.
+ IWorkbenchWindow window = fInput.getContext().getWindow();
+ if (window != null) {
+ IDebugContextService debugContextService = DebugUITools.getDebugContextManager().getContextService(window);
+ debugContextService.removeDebugContextListener(fDebugContextListener);
+ }
+
+ }
+
+ void proxyInstalled(BreakpointManagerProxy proxy) {
+ ModelDelta rootDelta = null;
+ synchronized(this) {
+ fProxies.add(proxy);
+
+ // Generate an install delta
+
+ rootDelta = new ModelDelta(fInput, 0, IModelDelta.NO_CHANGE, -1);
+ buildInstallDelta(rootDelta, fContainer);
+
+ if (DEBUG_BREAKPOINT_DELTAS) {
+ System.out.println("PROXY INSTALLED (" + proxy + ")\n"); //$NON-NLS-1$ //$NON-NLS-2$
+ }
+
+ proxy.postModelChanged(rootDelta, false);
+ }
+ }
+
+ synchronized void proxyDisposed(BreakpointManagerProxy proxy) {
+ fProxies.remove(proxy);
+ if (DEBUG_BREAKPOINT_DELTAS) {
+ System.out.println("PROXY DISPOSED (" + proxy + ")\n"); //$NON-NLS-1$ //$NON-NLS-2$
+ }
+ }
+
+ synchronized BreakpointManagerProxy[] getProxies() {
+ return (BreakpointManagerProxy[])fProxies.toArray(new BreakpointManagerProxy[fProxies.size()]);
+ }
+
+ /**
+ * Change the breakpoint organizers for the root container.
+ *
+ * @param organizers the new organizers.
+ */
+ void setOrganizers(IBreakpointOrganizer[] organizers) {
+ IBreakpointOrganizer[] oldOrganizers = null;
+ synchronized(this) {
+ oldOrganizers = fOrganizers;
+ fOrganizers = organizers;
+ }
+ registerOrganizersListener(oldOrganizers, organizers);
+ updateContainers();
+ }
+
+ private void registerOrganizersListener(IBreakpointOrganizer[] oldOrganizers, IBreakpointOrganizer[] newOrganizers) {
+ if (oldOrganizers != null) {
+ for (int i = 0; i < oldOrganizers.length; i++) {
+ oldOrganizers[i].removePropertyChangeListener(fOrganizersListener);
+ }
+ }
+ if (newOrganizers != null) {
+ for (int i = 0; i < newOrganizers.length; i++) {
+ newOrganizers[i].addPropertyChangeListener(fOrganizersListener);
+ }
+ }
+ }
+
+ void updateContainers() {
+ IBreakpoint[] breakpoints = filterBreakpoints(
+ fInput, getSelectionFilter(fInput, getDebugContext()), fBpManager.getBreakpoints());
+
+ synchronized(this) {
+ ModelDelta delta = new ModelDelta(fInput, IModelDelta.NO_CHANGE);
+ // create a reference container, use for deleting elements and adding elements
+ ModelDelta dummyDelta = new ModelDelta(null, IModelDelta.NO_CHANGE);
+ BreakpointContainer refContainer = createRootContainer(dummyDelta, fInput, fOrganizers, breakpoints);
+
+ // delete the removed elements
+ deleteRemovedElements(fContainer, refContainer, delta);
+
+ // adjust the old organizer with the reference organizer
+ BreakpointContainer.copyOrganizers(fContainer, refContainer);
+
+ // insert the added elements
+ IBreakpoint newBreakpoint = insertAddedElements(fContainer, refContainer, delta);
+ delta.setChildCount(fContainer.getChildren().length);
+
+ // select the new breakpoint
+ if (newBreakpoint != null) {
+ appendModelDeltaToElement(delta, newBreakpoint, IModelDelta.SELECT);
+ }
+ if (DEBUG_BREAKPOINT_DELTAS) {
+ System.out.println("POST BREAKPOINT DELTA (setOrganizers)\n"); //$NON-NLS-1$
+ }
+ postModelChanged(delta, false);
+ }
+ }
+
+ private synchronized IStructuredSelection getDebugContext() {
+ return fDebugContext;
+ }
+
+ /**
+ * Handles the property changed events in presentation contexts.
+ * Sub-classes may override to perform additional handling.
+ *
+ * @param presentation Presentation context that changed.
+ */
+ private void presentationPropertyChanged(PropertyChangeEvent event) {
+ if (IPresentationContext.PROPERTY_DISPOSED.equals(event.getProperty())) {
+ contextDisposed(fInput.getContext());
+ }
+ if (IBreakpointUIConstants.PROP_BREAKPOINTS_ORGANIZERS.equals(event.getProperty())) {
+ IBreakpointOrganizer[] organizers = (IBreakpointOrganizer[])event.getNewValue();
+ setOrganizers(organizers);
+ }
+ else if ( IBreakpointUIConstants.PROP_BREAKPOINTS_FILTER_SELECTION.equals(event.getProperty()) )
+ {
+ IStructuredSelection selection = null;
+
+ if (Boolean.TRUE.equals(event.getNewValue()) ) {
+ selection = getDebugContext();
+ }
+ setFilterSelection(selection);
+ }
+ else if ( IBreakpointUIConstants.PROP_BREAKPOINTS_TRACK_SELECTION.equals(event.getProperty()) )
+ {
+ IStructuredSelection selection = null;
+
+ if (Boolean.TRUE.equals(event.getNewValue()) ) {
+ selection = getDebugContext();
+ }
+ trackSelection(selection);
+ }
+ }
+
+ private void debugContextChanged(DebugContextEvent event) {
+ IStructuredSelection newContext;
+ if (event.getContext() instanceof IStructuredSelection) {
+ newContext = (IStructuredSelection)event.getContext();
+ } else {
+ newContext = StructuredSelection.EMPTY;
+ }
+
+ synchronized(this) {
+ fDebugContext = newContext;
+ }
+
+ if (Boolean.TRUE.equals(fInput.getContext().getProperty(IBreakpointUIConstants.PROP_BREAKPOINTS_FILTER_SELECTION)) ) {
+ setFilterSelection(newContext);
+ }
+
+ if (Boolean.TRUE.equals(fInput.getContext().getProperty(IBreakpointUIConstants.PROP_BREAKPOINTS_TRACK_SELECTION)) ) {
+ trackSelection(newContext);
+ }
+ }
+
+
+ private void setFilterSelection(IStructuredSelection ss) {
+ ModelDelta delta = new ModelDelta(fInput, IModelDelta.NO_CHANGE);
+ boolean changed = false;
+
+ // calculate supported breakpoints outside of the synchronized section.
+ IBreakpoint[] allBreakpoints = fBpManager.getBreakpoints();
+ boolean[] supportedBreakpoints = new boolean[allBreakpoints.length];
+ for (int i = 0; i < allBreakpoints.length; ++i) {
+ supportedBreakpoints[i] = supportsBreakpoint(ss, allBreakpoints[i]);
+ }
+
+ synchronized(this) {
+ Set existingBreakpoints = new HashSet(Arrays.asList(fContainer.getBreakpoints()));
+
+ // Bug 310879
+ // Process breakpoints in two passes: first remove breakpoints, then add new ones.
+ // This way the breakpoint counts and indexes will be consistent in the delta.
+ for (int i = 0; i < allBreakpoints.length; ++i) {
+ if (!supportedBreakpoints[i] && existingBreakpoints.contains(allBreakpoints[i])) {
+ fContainer.removeBreakpoint(allBreakpoints[i], delta);
+ changed = true;
+ }
+ }
+ for (int i = 0; i < allBreakpoints.length; ++i) {
+ if (supportedBreakpoints[i] && !existingBreakpoints.contains(allBreakpoints[i])) {
+ fContainer.addBreakpoint(allBreakpoints[i], delta);
+ changed = true;
+ }
+ }
+
+ if (changed) {
+ if (DEBUG_BREAKPOINT_DELTAS) {
+ System.out.println("POST BREAKPOINT DELTA (setFilterSelection)\n"); //$NON-NLS-1$
+ }
+ postModelChanged(delta, false);
+ }
+ }
+ }
+
+
+ private void trackSelection(IStructuredSelection selection) {
+ if (selection == null || selection.size() != 1) {
+ return;
+ }
+
+ Iterator iter = selection.iterator();
+ Object firstElement = iter.next();
+ if (firstElement == null || iter.hasNext()) {
+ return;
+ }
+ IThread thread = null;
+ if (firstElement instanceof IStackFrame) {
+ thread = ((IStackFrame) firstElement).getThread();
+ } else if (firstElement instanceof IThread) {
+ thread = (IThread) firstElement;
+ } else {
+ return;
+ }
+
+ IBreakpoint[] breakpoints = thread.getBreakpoints();
+ Set bpsSet = new HashSet(breakpoints.length * 4/3);
+ for (int i = 0; i< breakpoints.length; i++) {
+ bpsSet.add(breakpoints[i]);
+ }
+
+ ModelDelta delta = new ModelDelta(fInput, IModelDelta.NO_CHANGE);
+ synchronized (this) {
+ if (buildTrackSelectionDelta(delta, fContainer, bpsSet)) {
+ if (DEBUG_BREAKPOINT_DELTAS) {
+ System.out.println("POST BREAKPOINT DELTA (trackSelection)\n"); //$NON-NLS-1$
+ }
+ BreakpointManagerProxy[] proxies = getProxies();
+ for (int i = 0; i < proxies.length; i++) {
+ proxies[i].postModelChanged(delta, true);
+ }
+ }
+ }
+
+ }
+
+ /**
+ * Recursive function to build the model delta to select a breakpoint
+ * corresponding to the active debug context selection.
+ *
+ * @param delta Delta node to build on
+ * @param container Container element to build delta for.
+ * @param breakpoints Breakpoint set to be selected.
+ * @return whether we found a breakpoint to select
+ */
+ private boolean buildTrackSelectionDelta(ModelDelta delta, BreakpointContainer container, Set breakpoints) {
+ Object[] children = container.getChildren();
+ delta.setChildCount(children.length);
+ for (int i = 0; i < children.length; i++) {
+ ModelDelta childDelta = delta.addNode(children[i], i, IModelDelta.NO_CHANGE);
+ if (children[i] instanceof BreakpointContainer) {
+ BreakpointContainer childContainer = (BreakpointContainer)children[i];
+ boolean containsBP = false;
+ IBreakpoint[] containerBPs = childContainer.getBreakpoints();
+ for (int j = 0; j < containerBPs.length; j++) {
+ if (breakpoints.contains(containerBPs[j])) {
+ containsBP = true;
+ break;
+ }
+ }
+ if (containsBP && buildTrackSelectionDelta(childDelta, childContainer, breakpoints) ) {
+ return true;
+ }
+ } else if (children[i] instanceof IBreakpoint &&
+ breakpoints.contains(children[i]))
+ {
+ childDelta.setFlags(IModelDelta.SELECT | IModelDelta.EXPAND);
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Helper method to add breakpoints to the given input.
+ *
+ * @param data the input to add the breakpoints
+ * @param breakpoints the breakpoints
+ */
+ void breakpointsAdded(IBreakpoint[] breakpoints) {
+ IBreakpoint[] filteredBreakpoints = filterBreakpoints(
+ fInput, getSelectionFilter(fInput, getDebugContext()), breakpoints);
+
+ if (filteredBreakpoints.length > 0) {
+ synchronized (this) {
+ ModelDelta delta = new ModelDelta(fInput, 0, IModelDelta.NO_CHANGE, -1);
+ for (int i = 0; i < filteredBreakpoints.length; ++i) {
+ // Avoid adding breakpoints which were already removed. If breakpoints
+ // are added and removed very fast, the Breakpoint manager can issue
+ // breakpoint added events after breakpoint removed events! This means
+ // that such breakpoints would never be removed from the view.
+ // (Bug 289526)
+ if (DebugPlugin.getDefault().getBreakpointManager().getBreakpoint(filteredBreakpoints[i].getMarker()) != null) {
+ fContainer.addBreakpoint(filteredBreakpoints[i], delta);
+ }
+ }
+ delta.setChildCount(fContainer.getChildren().length);
+
+ // select the breakpoint
+ if (filteredBreakpoints.length > 0) {
+ appendModelDeltaToElement(delta, filteredBreakpoints[0], IModelDelta.SELECT);
+ }
+
+ if (DEBUG_BREAKPOINT_DELTAS) {
+ System.out.println("POST BREAKPOINT DELTA (breakpointsAddedInput)\n"); //$NON-NLS-1$
+ }
+ postModelChanged(delta, false);
+ }
+ }
+ }
+
+ /**
+ * Helper method to remove breakpoints from a given input.
+ *
+ * @param data the input to add the breakpoints
+ * @param breakpoints the breakpoints
+ */
+ void breakpointsRemoved(IBreakpoint[] breakpoints) {
+ synchronized (this) {
+ boolean removed = false;
+ ModelDelta delta = new ModelDelta(fInput, IModelDelta.NO_CHANGE);
+ for (int i = 0; i < breakpoints.length; ++i) {
+ removed = fContainer.removeBreakpoint(breakpoints[i], delta) || removed;
+ }
+
+ if (removed) {
+ if (DEBUG_BREAKPOINT_DELTAS) {
+ System.out.println("POST BREAKPOINT DELTA (breakpointsRemovedInput)\n"); //$NON-NLS-1$
+ }
+ postModelChanged(delta, false);
+ }
+ }
+ }
+
+ void breakpointsChanged(IBreakpoint[] breakpoints) {
+
+
+ IBreakpoint[] filteredBreakpoints = filterBreakpoints(
+ fInput, getSelectionFilter(fInput, getDebugContext()), breakpoints);
+
+ synchronized (this) {
+ ModelDelta delta = new ModelDelta(fInput, IModelDelta.NO_CHANGE);
+
+ // If the change caused a breakpoint to be added (installed) or remove (un-installed) update accordingly.
+ List removed = new ArrayList();
+ List added = new ArrayList();
+ List filteredAsList = Arrays.asList(filteredBreakpoints);
+ for (int i = 0; i < breakpoints.length; i++) {
+ IBreakpoint bp = breakpoints[i];
+ boolean oldContainedBp = fContainer.contains(bp);
+ boolean newContained = filteredAsList.contains(bp);
+ if (oldContainedBp && !newContained) {
+ removed.add(bp);
+ } else if (!oldContainedBp && newContained) {
+ added.add(bp);
+ }
+ }
+ if (!added.isEmpty()) {
+ breakpointsAdded((IBreakpoint[]) added.toArray(new IBreakpoint[added.size()]));
+ }
+ if (!removed.isEmpty()) {
+ breakpointsRemoved((IBreakpoint[]) removed.toArray(new IBreakpoint[removed.size()]));
+ }
+ for (int i = 0; i < filteredBreakpoints.length; ++i)
+ appendModelDelta(fContainer, delta, IModelDelta.STATE | IModelDelta.CONTENT, filteredBreakpoints[i]); // content flag triggers detail refresh
+
+ if (DEBUG_BREAKPOINT_DELTAS) {
+ System.out.println("POST BREAKPOINT DELTA (breakpointsChanged)\n"); //$NON-NLS-1$
+ }
+ postModelChanged(delta, false);
+ }
+ }
+
+
+ /**
+ * Recursive function to build the model delta to install breakpoint
+ * model proxies for all breakpoints and breakpoint containers.
+ *
+ * @param delta Delta node to build on
+ * @param container Container element to build delta for.
+ */
+ private void buildInstallDelta(ModelDelta delta, BreakpointContainer container) {
+ Object[] children = container.getChildren();
+ delta.setChildCount(children.length);
+ for (int i = 0; i < children.length; i++) {
+ ModelDelta childDelta = delta.addNode(children[i], i, IModelDelta.NO_CHANGE);
+ if (children[i] instanceof BreakpointContainer) {
+ childDelta.setFlags(IModelDelta.INSTALL);
+ buildInstallDelta(childDelta, (BreakpointContainer)children[i]);
+ } else if (children[i] instanceof IBreakpoint) {
+ childDelta.setFlags(IModelDelta.INSTALL);
+ }
+ }
+ }
+
+
+ /**
+ * Insert elements from the reference container to an existing container.
+ *
+ * @param container the existing container to insert the new elements.
+ * @param refContainer the reference container to compare elements that are added.
+ * @param containerDelta the delta of the existing container.
+ */
+ private IBreakpoint insertAddedElements(BreakpointContainer container, BreakpointContainer refContainer, ModelDelta containerDelta) {
+ IBreakpoint newBreakpoint = null;
+
+ Object[] children = container.getChildren();
+ Object[] refChildren = refContainer.getChildren();
+
+
+ for (int i = 0; i < refChildren.length; ++i) {
+ Object element = getElement(children, refChildren[i]);
+
+ // if a child of refContainer doesn't exist in container, than insert it to container
+ // - if the reference child is a container, than copy the reference child container to container
+ // - otherwise (Breakpoint), add the breakpoint to container
+ if (element == null) {
+ if (refChildren[i] instanceof BreakpointContainer) {
+ BreakpointContainer.addChildContainer(container, (BreakpointContainer) refChildren[i], containerDelta);
+ } else {
+ BreakpointContainer.addBreakpoint(container, (IBreakpoint) refChildren[i], containerDelta);
+ if (newBreakpoint == null)
+ newBreakpoint = (IBreakpoint) refChildren[i];
+ }
+
+ // if a child exist in container, than recursively search into container. And also update the organizer of
+ // of container to the one in the refContainer's child.
+ } else if (element instanceof BreakpointContainer) {
+ int index = Arrays.asList(children).indexOf(element);
+ ModelDelta childDelta = containerDelta.addNode(element, index, IModelDelta.STATE, -1);
+ BreakpointContainer.copyOrganizers((BreakpointContainer) element, (BreakpointContainer) refChildren[i]);
+ newBreakpoint = insertAddedElements((BreakpointContainer) element, (BreakpointContainer) refChildren[i], childDelta);
+ childDelta.setChildCount(((BreakpointContainer) element).getChildren().length);
+ }
+ }
+
+ return newBreakpoint;
+ }
+
+ /**
+ * Delete elements from existing container that doesn't exist in the reference container.
+ *
+ * @param container the existing container to delete the removed elements.
+ * @param refContainer the reference container to compare elements that are removed.
+ * @param containerDelta the delta of the existing container.
+ */
+ private void deleteRemovedElements(BreakpointContainer container, BreakpointContainer refContainer, ModelDelta containerDelta) {
+ Object[] children = container.getChildren();
+ Object[] refChildren = refContainer.getChildren();
+
+ // if a child of container doesn't exist in refContainer, than remove it from container
+ for (int i = 0; i < children.length; ++i) {
+ Object element = getElement(refChildren, children[i]);
+
+ if (element == null) {
+ if (children[i] instanceof BreakpointContainer) {
+ BreakpointContainer.removeAll((BreakpointContainer) children[i], containerDelta);
+ } else {
+ BreakpointContainer.removeBreakpoint(container, (IBreakpoint) children[i], containerDelta);
+ }
+ } else if (element instanceof BreakpointContainer){
+
+ ModelDelta childDelta = containerDelta.addNode(children[i], IModelDelta.STATE);
+ deleteRemovedElements((BreakpointContainer) children[i], (BreakpointContainer) element, childDelta);
+ }
+ }
+ }
+
+ /**
+ * Get the element that is in the collection.
+ *
+ * @param collection the collection of elements.
+ * @param element the element to search.
+ * @return if element exist in collection, than it is returned, otherwise <code>null</code> is returned.
+ * @see insertAddedElements
+ * @see deleteRemovedElements
+ */
+ private Object getElement(Object[] collection, Object element) {
+ for (int i = 0; i < collection.length; ++i)
+ if (collection[i] instanceof BreakpointContainer && element instanceof BreakpointContainer) {
+ if (collection[i].equals(element))
+ return collection[i];
+ } else {
+ if (collection[i].equals(element))
+ return collection[i];
+ }
+ return null;
+ }
+
+ /**
+ * Create a root container.
+ *
+ * @param rootDelta the root delta.
+ * @param input the view input.
+ * @param organizers the breakpoint organizers.
+ * @param oldContainer the old container, use to determine whether a new breakpoint should be expanded.
+ * @param the breakpoint manager.
+ */
+ private BreakpointContainer createRootContainer(
+ ModelDelta rootDelta, DefaultBreakpointsViewInput input,
+ IBreakpointOrganizer[] organizers, IBreakpoint[] breakpoints)
+ {
+
+ BreakpointContainer container = new BreakpointContainer(organizers, fComparator);
+ container.initDefaultContainers(rootDelta);
+
+ for (int i = 0; i < breakpoints.length; ++i) {
+ container.addBreakpoint(breakpoints[i], rootDelta);
+ }
+
+ return container;
+ }
+
+ /**
+ * Fire model change event for the input.
+ *
+ * @param input the input.
+ * @param delta the model delta.
+ * @param debugReason the debug string.
+ */
+ synchronized private void postModelChanged(final IModelDelta delta, boolean select) {
+ for (int i = 0; fProxies != null && i < fProxies.size(); i++) {
+ ((BreakpointManagerProxy)fProxies.get(i)).postModelChanged(delta, select);
+ }
+ }
+
+
+ }
+
+ private class InputDataMap extends LinkedHashMap {
+ private static final long serialVersionUID = 1L;
+
+ public InputDataMap() {
+ super(1, (float)0.75, true);
+ }
+
+ protected boolean removeEldestEntry(java.util.Map.Entry arg0) {
+ InputData data = (InputData)arg0.getValue();
+ if (size() > getMaxInputsCache() && data.fProxies.isEmpty()) {
+ data.dispose();
+ return true;
+ }
+ return false;
+ }
+ }
+
+ /**
+ * Scheduling rule to make sure that breakpoint manager listener updates
+ * are process serially.
+ */
+ private ISchedulingRule fBreakpointsListenerSchedulingRule = new ISchedulingRule() {
+
+ public boolean isConflicting(ISchedulingRule rule) {
+ return rule == this;
+ }
+
+ public boolean contains(ISchedulingRule rule) {
+ return rule == this;
+ }
+ };
+
+ // debug flags
+ public static boolean DEBUG_BREAKPOINT_DELTAS = false;
+
+ static {
+ DEBUG_BREAKPOINT_DELTAS = DebugUIPlugin.DEBUG && "true".equals( //$NON-NLS-1$
+ Platform.getDebugOption("org.eclipse.debug.ui/debug/viewers/breakpointDeltas")); //$NON-NLS-1$
+ }
+
+ /**
+ * A map of input to info data cache
+ */
+ final private Map fInputToData = Collections.synchronizedMap(new InputDataMap());
+
+ /**
+ * Flag indicating whether the content provider is currently a breakpoints listener.
+ */
+ private boolean fIsBreakpointListener = false;
+
+ /**
+ * The breakpoint manager.
+ */
+ final private IBreakpointManager fBpManager = DebugPlugin.getDefault().getBreakpointManager();
+
+ /**
+ * Sub-classes may override this method to filter the breakpoints.
+ *
+ * @param input the breakpoint manager input.
+ * @param breakpoints the list of breakpoint to filter.
+ * @return the filtered list of breakpoint based on the input.
+ */
+ protected IBreakpoint[] filterBreakpoints(DefaultBreakpointsViewInput input, IStructuredSelection selectionFilter, IBreakpoint[] breakpoints) {
+ if (selectionFilter != null && !selectionFilter.isEmpty()) {
+ List targets = getDebugTargets(selectionFilter);
+ ArrayList retVal = new ArrayList();
+ if (targets != null) {
+ for (int i = 0; i < breakpoints.length; ++i) {
+ if (supportsBreakpoint(targets, breakpoints[i]))
+ retVal.add(breakpoints[i]);
+ }
+ }
+ return (IBreakpoint[]) retVal.toArray(new IBreakpoint[retVal.size()]);
+ } else {
+ return breakpoints;
+ }
+ }
+
+ /**
+ * Sub-classes may override this to determine whether the breakpoint is supported by the selection.
+ *
+ * @param ss the selection of the debug elements.
+ * @param breakpoint the breakpoint.
+ * @return true if supported.
+ */
+ protected boolean supportsBreakpoint(IStructuredSelection ss, IBreakpoint breakpoint) {
+ return supportsBreakpoint(getDebugTargets(ss), breakpoint);
+ }
+
+ /**
+ * Returns true if the breakpoint contains in one of the targets.
+ *
+ * @param targets a list of <code>IDebugTarget</code> objects.
+ * @param breakpoint the breakpoint.
+ * @return true if breakpoint contains in the list of targets.
+ */
+ protected boolean supportsBreakpoint(List targets, IBreakpoint breakpoint) {
+ boolean exist = targets.size() == 0 ? true : false;
+ for (int i = 0; !exist && i < targets.size(); ++i) {
+ IDebugTarget target = (IDebugTarget) targets.get(i);
+ exist |= target.supportsBreakpoint(breakpoint);
+ }
+ return exist;
+ }
+
+ /**
+ * Returns the list of IDebugTarget for the selection.
+ *
+ * @param ss the selection.
+ * @return list of IDebugTarget object.
+ */
+ protected List getDebugTargets(IStructuredSelection ss) {
+ List debugTargets = new ArrayList(2);
+ if (ss != null) {
+ Iterator i = ss.iterator();
+ while (i.hasNext()) {
+ Object next = i.next();
+ if (next instanceof IDebugElement) {
+ debugTargets.add(((IDebugElement)next).getDebugTarget());
+ } else if (next instanceof ILaunch) {
+ IDebugTarget[] targets = ((ILaunch)next).getDebugTargets();
+ for (int j = 0; j < targets.length; j++) {
+ debugTargets.add(targets[j]);
+ }
+ } else if (next instanceof IProcess) {
+ IDebugTarget target = (IDebugTarget)((IProcess)next).getAdapter(IDebugTarget.class);
+ if (target != null) {
+ debugTargets.add(target);
+ }
+ }
+ }
+ }
+ return debugTargets;
+ }
+
+
+ /**
+ * Maximum number of breakpoint manager input objects that this provider
+ * will cache data for. This method is called once upon class creation
+ * when setting up the data cache. Sub-classes may override to provide
+ * a custom setting.
+ *
+ * @return Maximum data cache size
+ */
+ protected int getMaxInputsCache() {
+ return 2;
+ }
+
+ /**
+ * Handles the event when a presentation context is dispoed.
+ * Sub-classes may override to perform additional cleanup.
+ *
+ * @param context Presetnation context that was disposed.
+ */
+ protected void contextDisposed(IPresentationContext context) {
+ List removed = new ArrayList(1);
+ synchronized (fInputToData) {
+ for (Iterator itr = fInputToData.entrySet().iterator(); itr.hasNext();) {
+ Map.Entry entry = (Map.Entry)itr.next();
+ IPresentationContext entryContext = ((DefaultBreakpointsViewInput)entry.getKey()).getContext();
+ if (context.equals(entryContext)) {
+ removed.add(entry.getValue());
+ itr.remove();
+ }
+ }
+ }
+
+ // Dispose the removed input datas
+ for (int i = 0; i < removed.size(); i++) {
+ ((InputData)removed.get(i)).dispose();
+ }
+ }
+
+ /**
+ * Register the breakpoint manager input with this content provider.
+ *
+ * @param input the breakpoint manager input to register.
+ * @param proxy the model proxy of the input.
+ * @param organizers the breakpoint organizer, can be <code>null</code>.
+ * @param selectionFilter the selection filter, can be <code>null</code>.
+ * @param comparator the element comparator.
+ */
+ public void registerModelProxy(DefaultBreakpointsViewInput input, BreakpointManagerProxy proxy) {
+ synchronized(this) {
+ if (!fIsBreakpointListener) {
+ fBpManager.addBreakpointListener(this);
+ fIsBreakpointListener = true;
+ }
+ }
+ InputData inputData = getInputData(input);
+ if (inputData != null) {
+ inputData.proxyInstalled(proxy);
+ }
+ }
+
+ /**
+ * Unregister the breakpoint manager input with this content provider.
+ *
+ * @param input the breakpoint manager input to unregister.
+ */
+ public void unregisterModelProxy(DefaultBreakpointsViewInput input, BreakpointManagerProxy proxy) {
+ InputData inputData = (InputData)fInputToData.get(input);
+ if (inputData != null) {
+ inputData.proxyDisposed(proxy);
+
+ if (fInputToData.isEmpty()) {
+ synchronized(this) {
+ if (fIsBreakpointListener) {
+ fBpManager.removeBreakpointListener(this);
+ fIsBreakpointListener = false;
+ }
+ }
+ }
+ }
+ }
+
+ private InputData getInputData(DefaultBreakpointsViewInput input) {
+ if (Boolean.TRUE.equals(input.getContext().getProperty(IPresentationContext.PROPERTY_DISPOSED)) ) {
+ return null;
+ }
+
+ InputData data = null;
+ synchronized (fInputToData) {
+ data = (InputData)fInputToData.get(input);
+ if (data == null) {
+ data = new InputData(input);
+ fInputToData.put(input, data);
+ }
+ }
+ return data;
+ }
+
+ /**
+ * Returns the selection filter for the input.
+ *
+ * @param input the selection.
+ */
+ protected IStructuredSelection getSelectionFilter(Object input, IStructuredSelection debugContext) {
+ if (input instanceof DefaultBreakpointsViewInput) {
+ IPresentationContext presentation = ((DefaultBreakpointsViewInput)input).getContext();
+ if ( Boolean.TRUE.equals(presentation.getProperty(IBreakpointUIConstants.PROP_BREAKPOINTS_FILTER_SELECTION)) ) {
+ return debugContext;
+ }
+ }
+ return null;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.debug.internal.ui.model.elements.ElementContentProvider#supportsContextId(java.lang.String)
+ */
+ protected boolean supportsContextId(String id) {
+ return id.equals(IDebugUIConstants.ID_BREAKPOINT_VIEW);
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.debug.internal.ui.model.elements.ElementContentProvider#getChildCount(java.lang.Object, org.eclipse.debug.internal.ui.viewers.model.provisional.IPresentationContext, org.eclipse.debug.internal.ui.viewers.model.provisional.IViewerUpdate)
+ */
+ protected int getChildCount(Object element, IPresentationContext context, IViewerUpdate monitor) throws CoreException {
+ Object input = monitor.getViewerInput();
+ if (input instanceof DefaultBreakpointsViewInput) {
+ DefaultBreakpointsViewInput bpManagerInput = (DefaultBreakpointsViewInput)input;
+ InputData inputData = getInputData(bpManagerInput);
+ if (inputData != null) {
+ return inputData.fContainer.getChildren().length;
+ }
+ }
+ return 0;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.debug.internal.ui.model.elements.ElementContentProvider#getChildren(java.lang.Object, int, int, org.eclipse.debug.internal.ui.viewers.model.provisional.IPresentationContext, org.eclipse.debug.internal.ui.viewers.model.provisional.IViewerUpdate)
+ */
+ protected Object[] getChildren(Object parent, int index, int length, IPresentationContext context, IViewerUpdate monitor) throws CoreException {
+ Object input = monitor.getViewerInput();
+ if (input instanceof DefaultBreakpointsViewInput) {
+ DefaultBreakpointsViewInput bpManagerInput = (DefaultBreakpointsViewInput)input;
+ InputData inputData = getInputData(bpManagerInput);
+ if (inputData != null) {
+ Object[] children = inputData.fContainer.getChildren();
+ return getElements(children, index, length);
+ }
+ }
+
+ return EMPTY;
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see org.eclipse.debug.core.IBreakpointsListener#breakpointsAdded(org.eclipse.debug.core.model.IBreakpoint[])
+ */
+ public void breakpointsAdded(final IBreakpoint[] breakpoints) {
+ new Job("Breakpoints View Update Job") { //$NON-NLS-1$
+ {
+ setSystem(true);
+ setRule(fBreakpointsListenerSchedulingRule);
+ }
+
+ protected IStatus run(IProgressMonitor monitor) {
+ InputData[] datas = (InputData[])fInputToData.values().toArray(new InputData[0]);
+ for (int i = 0; i < datas.length; i++) {
+ datas[i].breakpointsAdded(breakpoints);
+ }
+ return Status.OK_STATUS;
+ }
+ }.schedule();
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see org.eclipse.debug.core.IBreakpointsListener#breakpointsRemoved(org.eclipse.debug.core.model.IBreakpoint[], org.eclipse.core.resources.IMarkerDelta[])
+ */
+ public void breakpointsRemoved(final IBreakpoint[] breakpoints, IMarkerDelta[] deltas) {
+ new Job("Breakpoints View Update Job") { //$NON-NLS-1$
+ {
+ setSystem(true);
+ setRule(fBreakpointsListenerSchedulingRule);
+ }
+
+ protected IStatus run(IProgressMonitor monitor) {
+ InputData[] datas = (InputData[])fInputToData.values().toArray(new InputData[0]);
+ for (int i = 0; i < datas.length; i++) {
+ datas[i].breakpointsRemoved(breakpoints);
+ }
+ return Status.OK_STATUS;
+ }
+ }.schedule();
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see org.eclipse.debug.core.IBreakpointsListener#breakpointsChanged(org.eclipse.debug.core.model.IBreakpoint[], org.eclipse.core.resources.IMarkerDelta[])
+ */
+ public void breakpointsChanged(final IBreakpoint[] breakpoints, IMarkerDelta[] deltas) {
+ new Job("Breakpoints View Update Job") { //$NON-NLS-1$
+ {
+ setSystem(true);
+ setRule(fBreakpointsListenerSchedulingRule);
+ }
+
+ protected IStatus run(IProgressMonitor monitor) {
+ InputData[] datas = (InputData[])fInputToData.values().toArray(new InputData[0]);
+ for (int i = 0; i < datas.length; i++) {
+ datas[i].breakpointsChanged(breakpoints);
+ }
+ return Status.OK_STATUS;
+ }
+ }.schedule();
+ }
+ /**
+ * Appends the model delta flags to child containers that contains the breakpoint.
+ *
+ * @param parent the parent container.
+ * @param parentDelta the parent model delta.
+ * @param flags the model delta flags.
+ * @param breakpoint the breakpoint to search in the children containers.
+ */
+ private void appendModelDelta(BreakpointContainer parent, ModelDelta parentDelta, int flags, IBreakpoint breakpoint) {
+ BreakpointContainer[] containers = parent.getContainers();
+
+ if (parent.contains(breakpoint)) {
+ if ((containers.length != 0)) {
+ for (int i = 0; i < containers.length; ++i) {
+ ModelDelta nodeDelta = parentDelta.addNode(containers[i], IModelDelta.STATE);
+ appendModelDelta(containers[i], nodeDelta, flags, breakpoint);
+ }
+ } else {
+ parentDelta.addNode(breakpoint, flags);
+ }
+ }
+ }
+
+ /**
+ * Appends the model delta to the first found element in the model delta tree.
+ *
+ * @param parentDelta the parent delta
+ * @param element the element to search
+ * @param flags the delta flags
+ */
+ private void appendModelDeltaToElement(IModelDelta parentDelta, Object element, int flags) {
+ if (element.equals(parentDelta.getElement())) {
+ ((ModelDelta) parentDelta).setFlags(parentDelta.getFlags() | flags);
+ return;
+ }
+
+ IModelDelta[] childDeltas = parentDelta.getChildDeltas();
+ for (int i = 0; i < childDeltas.length; ++i) {
+ if (element.equals(childDeltas[i].getElement())) {
+ ((ModelDelta) childDeltas[i]).setFlags(childDeltas[i].getFlags() | flags);
+ return;
+ }
+
+ appendModelDeltaToElement(childDeltas[i], element, flags);
+ }
+ }
+}

Back to the top