| /******************************************************************************* |
| * Copyright (c) 2000, 2009 IBM Corporation 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: |
| * IBM Corporation - initial API and implementation |
| *******************************************************************************/ |
| package org.eclipse.debug.internal.ui.views.breakpoints; |
| |
| import java.util.ArrayList; |
| import java.util.HashMap; |
| import java.util.HashSet; |
| import java.util.Iterator; |
| import java.util.List; |
| import java.util.Map; |
| import java.util.Set; |
| import java.util.Map.Entry; |
| |
| import org.eclipse.core.resources.IMarker; |
| import org.eclipse.core.resources.IMarkerDelta; |
| import org.eclipse.core.runtime.CoreException; |
| import org.eclipse.core.runtime.IAdaptable; |
| import org.eclipse.debug.core.DebugPlugin; |
| import org.eclipse.debug.core.IBreakpointManager; |
| import org.eclipse.debug.core.IBreakpointsListener; |
| import org.eclipse.debug.core.model.IBreakpoint; |
| import org.eclipse.debug.internal.core.IInternalDebugCoreConstants; |
| import org.eclipse.debug.internal.ui.DebugUIPlugin; |
| import org.eclipse.debug.internal.ui.IInternalDebugUIConstants; |
| import org.eclipse.debug.internal.ui.importexport.breakpoints.IImportExportConstants; |
| import org.eclipse.debug.ui.AbstractBreakpointOrganizerDelegate; |
| import org.eclipse.debug.ui.IBreakpointOrganizerDelegateExtension; |
| import org.eclipse.debug.ui.IDebugUIConstants; |
| import org.eclipse.jface.preference.IPreferenceStore; |
| import org.eclipse.jface.util.IPropertyChangeListener; |
| import org.eclipse.jface.util.PropertyChangeEvent; |
| import org.eclipse.ui.IWorkingSet; |
| import org.eclipse.ui.IWorkingSetManager; |
| import org.eclipse.ui.PlatformUI; |
| |
| /** |
| * Breakpoint organizers for breakpoint working sets. |
| * |
| * @since 3.1 |
| */ |
| public class BreakpointSetOrganizer extends AbstractBreakpointOrganizerDelegate implements IBreakpointOrganizerDelegateExtension, IPropertyChangeListener, IBreakpointsListener { |
| |
| private IWorkingSetManager fWorkingSetManager = PlatformUI.getWorkbench().getWorkingSetManager(); |
| |
| /** |
| * A cache for mapping markers to the working set they belong to |
| * @since 3.2 |
| */ |
| private BreakpointWorkingSetCache fCache = null; |
| |
| // Cache of the default working set, so we can know when it changes name |
| private static IWorkingSet fDefaultWorkingSet = null; |
| |
| |
| /** |
| * Constructs a working set breakpoint organizer. Listens for changes in |
| * working sets and fires property change notification. |
| */ |
| public BreakpointSetOrganizer() { |
| fWorkingSetManager.addPropertyChangeListener(this); |
| fCache = new BreakpointWorkingSetCache(); |
| DebugUIPlugin.getDefault().getPreferenceStore().addPropertyChangeListener(this); |
| DebugPlugin.getDefault().getBreakpointManager().addBreakpointListener(this); |
| fDefaultWorkingSet = getDefaultWorkingSet(); |
| } |
| |
| /* |
| * (non-Javadoc) |
| * |
| * @see org.eclipse.debug.ui.IBreakpointOrganizerDelegate#getCategories(org.eclipse.debug.core.model.IBreakpoint) |
| */ |
| public IAdaptable[] getCategories(IBreakpoint breakpoint) { |
| List result = new ArrayList(); |
| IWorkingSet[] workingSets = fWorkingSetManager.getWorkingSets(); |
| for (int i = 0; i < workingSets.length; i++) { |
| IWorkingSet set = workingSets[i]; |
| if (IDebugUIConstants.BREAKPOINT_WORKINGSET_ID.equals(set.getId())) { |
| IAdaptable[] elements = set.getElements(); |
| for (int j = 0; j < elements.length; j++) { |
| IAdaptable adaptable = elements[j]; |
| if (adaptable.equals(breakpoint)) { |
| result.add(new WorkingSetCategory(set)); |
| break; |
| } |
| } |
| } |
| } |
| return (IAdaptable[]) result.toArray(new IAdaptable[result.size()]); |
| } |
| |
| /* |
| * (non-Javadoc) |
| * |
| * @see org.eclipse.debug.ui.IBreakpointOrganizerDelegate#dispose() |
| */ |
| public void dispose() { |
| fWorkingSetManager.removePropertyChangeListener(this); |
| fWorkingSetManager = null; |
| DebugPlugin.getDefault().getBreakpointManager().removeBreakpointListener(this); |
| DebugUIPlugin.getDefault().getPreferenceStore().removePropertyChangeListener(this); |
| super.dispose(); |
| } |
| |
| /* |
| * (non-Javadoc) |
| * |
| * @see org.eclipse.jface.util.IPropertyChangeListener#propertyChange(org.eclipse.jface.util.PropertyChangeEvent) |
| */ |
| public void propertyChange(PropertyChangeEvent event) { |
| String property = event.getProperty(); |
| if (property.equals(IInternalDebugUIConstants.MEMENTO_BREAKPOINT_WORKING_SET_NAME)) { |
| IWorkingSet defaultWorkingSet = getDefaultWorkingSet(); |
| if (defaultWorkingSet != null) { |
| fireCategoryChanged(new WorkingSetCategory(defaultWorkingSet)); |
| } else { |
| fireCategoryChanged(null); |
| } |
| } |
| |
| IWorkingSet set = null; |
| Object newValue = event.getNewValue(); |
| if (newValue instanceof IWorkingSet) { |
| set = (IWorkingSet) newValue; |
| } |
| else if (event.getOldValue() instanceof IWorkingSet) { |
| set = (IWorkingSet) event.getOldValue(); |
| } |
| if(set == null) { |
| return; |
| } |
| //fix for bug 103731 |
| if (property.equals(IWorkingSetManager.CHANGE_WORKING_SET_NAME_CHANGE)) { |
| if (newValue.equals(fDefaultWorkingSet)) { |
| setDefaultWorkingSet((IWorkingSet) newValue); |
| } |
| } |
| if (property.equals(IWorkingSetManager.CHANGE_WORKING_SET_REMOVE)) { |
| if (event.getOldValue().equals(fDefaultWorkingSet)) { |
| setDefaultWorkingSet(null); |
| } |
| } |
| if(property.equals(IWorkingSetManager.CHANGE_WORKING_SET_ADD)) { |
| IAdaptable[] breakpoints = set.getElements(); |
| for (int i = 0; i < breakpoints.length; i++) { |
| if (breakpoints[i] instanceof IBreakpoint) { |
| IMarker marker = ((IBreakpoint)breakpoints[i]).getMarker(); |
| fCache.addEntry(marker, set.getName()); |
| fCache.flushMarkerCache(marker); |
| } |
| } |
| } |
| if (set != null && IDebugUIConstants.BREAKPOINT_WORKINGSET_ID.equals(set.getId())) { |
| fireCategoryChanged(new WorkingSetCategory(set)); |
| } |
| } |
| |
| /* |
| * (non-Javadoc) |
| * |
| * @see org.eclipse.debug.core.IBreakpointsListener#breakpointsAdded(org.eclipse.debug.core.model.IBreakpoint[]) |
| */ |
| public void breakpointsAdded(IBreakpoint[] breakpoints) { |
| Map setToBreakpoints = new HashMap(); |
| for (int i = 0; i < breakpoints.length; i++) { |
| IMarker marker = breakpoints[i].getMarker(); |
| String[] names = getWorkingsetAttributeFromMarker(marker, IInternalDebugUIConstants.WORKING_SET_NAME); |
| //add it to the default set if the listing is empty |
| if (names.length == 0) { |
| queueToSet(breakpoints[i], getDefaultWorkingSet(), setToBreakpoints); |
| } else { |
| for (int j = 1; j < names.length; j++) { |
| IWorkingSet set = PlatformUI.getWorkbench().getWorkingSetManager().getWorkingSet(names[j]); |
| // if we cannot find the one we want, try to get the default |
| if (set == null) { |
| set = getDefaultWorkingSet(); |
| } |
| queueToSet(breakpoints[i], set, setToBreakpoints); |
| } |
| } |
| } |
| Iterator iterator = setToBreakpoints.entrySet().iterator(); |
| while (iterator.hasNext()) { |
| Entry entry = (Entry) iterator.next(); |
| IWorkingSet set = (IWorkingSet) entry.getKey(); |
| List list = (List) entry.getValue(); |
| addBreakpointsToSet((IBreakpoint[]) list.toArray(new IBreakpoint[list.size()]), set); |
| } |
| } |
| |
| private void queueToSet(IBreakpoint breakpoint, IWorkingSet set, Map queue) { |
| List list = (List) queue.get(set); |
| if (list == null) { |
| list = new ArrayList(); |
| queue.put(set, list); |
| } |
| list.add(breakpoint); |
| } |
| |
| /** |
| * Adds a breakpoint to a working set |
| * @param breakpoint the breakpoint to add |
| * @param set the set to add it to or <code>null</code> if none |
| * |
| * @since 3.2 |
| */ |
| private void addBreakpointsToSet(IBreakpoint[] breakpoints, IWorkingSet set) { |
| if (set != null) { |
| IAdaptable[] elements = set.getElements(); |
| Set collection = new HashSet(elements.length); |
| List list = new ArrayList(elements.length + breakpoints.length); |
| for(int i = 0; i < elements.length; i++) { |
| collection.add(elements[i]); |
| list.add(elements[i]); |
| } |
| for (int i = 0; i < breakpoints.length; i++) { |
| IBreakpoint breakpoint = breakpoints[i]; |
| if (!collection.contains(breakpoint)) { |
| list.add(breakpoint); |
| fCache.addEntry(breakpoint.getMarker(), set.getName()); //fix for bug 103731 |
| fCache.flushMarkerCache(breakpoint.getMarker()); |
| } |
| } |
| set.setElements((IAdaptable[]) list.toArray(new IAdaptable[list.size()])); |
| } |
| } |
| |
| /* |
| * (non-Javadoc) |
| * |
| * @see org.eclipse.debug.core.IBreakpointsListener#breakpointsRemoved(org.eclipse.debug.core.model.IBreakpoint[], |
| * org.eclipse.core.resources.IMarkerDelta[]) |
| */ |
| public void breakpointsRemoved(IBreakpoint[] breakpoints, |
| IMarkerDelta[] deltas) { |
| IWorkingSet[] workingSets = fWorkingSetManager.getWorkingSets(); |
| IWorkingSet set = null; |
| for (int i = 0; i < workingSets.length; i++) { |
| set = workingSets[i]; |
| if (IDebugUIConstants.BREAKPOINT_WORKINGSET_ID.equals(set.getId())) { |
| clean(set); |
| } |
| } |
| } |
| |
| /** |
| * Removes deleted breakpoints from the given working set. |
| * |
| * @param workingSet |
| * breakpoint working set |
| */ |
| private void clean(IWorkingSet workingSet) { |
| IAdaptable[] elements = workingSet.getElements(); |
| IBreakpointManager manager = DebugPlugin.getDefault().getBreakpointManager(); |
| boolean update = false; |
| for (int i = 0; i < elements.length; i++) { |
| IAdaptable adaptable = elements[i]; |
| if (adaptable instanceof IBreakpoint) { |
| IBreakpoint breakpoint = (IBreakpoint) adaptable; |
| if (!manager.isRegistered(breakpoint)) { |
| update = true; |
| elements[i] = null; |
| } |
| } |
| } |
| if (update) { |
| List newElements = new ArrayList(elements.length); |
| for (int i = 0; i < elements.length; i++) { |
| IAdaptable adaptable = elements[i]; |
| if (adaptable != null) { |
| newElements.add(adaptable); |
| } |
| } |
| workingSet.setElements((IAdaptable[]) newElements.toArray(new IAdaptable[newElements.size()])); |
| } |
| } |
| |
| /* |
| * (non-Javadoc) |
| * |
| * @see org.eclipse.debug.core.IBreakpointsListener#breakpointsChanged(org.eclipse.debug.core.model.IBreakpoint[], |
| * org.eclipse.core.resources.IMarkerDelta[]) |
| */ |
| public void breakpointsChanged(IBreakpoint[] breakpoints, IMarkerDelta[] deltas) { |
| } |
| |
| /** |
| * Returns the active default breakpoint working set, or <code>null</code> |
| * if none. |
| * |
| * @return the active default breakpoint working set, or <code>null</code> |
| */ |
| public static IWorkingSet getDefaultWorkingSet() { |
| IPreferenceStore preferenceStore = DebugUIPlugin.getDefault().getPreferenceStore(); |
| String name = preferenceStore.getString(IInternalDebugUIConstants.MEMENTO_BREAKPOINT_WORKING_SET_NAME); |
| if (name != null) { |
| return PlatformUI.getWorkbench().getWorkingSetManager().getWorkingSet(name); |
| } |
| return null; |
| } |
| |
| /** |
| * Sets the active default breakpoint working set, or <code>null</code> if |
| * none. |
| * |
| * @param set |
| * default working set or <code>null</code> |
| */ |
| public static void setDefaultWorkingSet(IWorkingSet set) { |
| String name = IInternalDebugCoreConstants.EMPTY_STRING; |
| if (set != null) { |
| // only consider breakpoint working sets |
| if (IDebugUIConstants.BREAKPOINT_WORKINGSET_ID.equals(set.getId())) { |
| name = set.getName(); |
| } |
| } |
| fDefaultWorkingSet = set; |
| DebugUIPlugin.getDefault().getPluginPreferences().setValue(IInternalDebugUIConstants.MEMENTO_BREAKPOINT_WORKING_SET_NAME, name); |
| } |
| |
| /* |
| * (non-Javadoc) |
| * |
| * @see org.eclipse.debug.ui.IBreakpointOrganizerDelegate#canRemove(org.eclipse.debug.core.model.IBreakpoint, |
| * org.eclipse.core.runtime.IAdaptable) |
| */ |
| public boolean canRemove(IBreakpoint breakpoint, IAdaptable category) { |
| if (category instanceof WorkingSetCategory) { |
| WorkingSetCategory wsc = (WorkingSetCategory) category; |
| return IDebugUIConstants.BREAKPOINT_WORKINGSET_ID.equals(wsc.getWorkingSet().getId()); |
| } |
| return super.canRemove(breakpoint, category); |
| } |
| |
| /* |
| * (non-Javadoc) |
| * |
| * @see org.eclipse.debug.ui.IBreakpointOrganizerDelegate#canAdd(org.eclipse.debug.core.model.IBreakpoint, |
| * org.eclipse.core.runtime.IAdaptable) |
| */ |
| public boolean canAdd(IBreakpoint breakpoint, IAdaptable category) { |
| if (category instanceof WorkingSetCategory) { |
| WorkingSetCategory wsc = (WorkingSetCategory) category; |
| return IDebugUIConstants.BREAKPOINT_WORKINGSET_ID.equals(wsc.getWorkingSet().getId()); |
| } |
| return super.canAdd(breakpoint, category); |
| } |
| |
| /* |
| * (non-Javadoc) |
| * |
| * @see org.eclipse.debug.ui.IBreakpointOrganizerDelegate#addBreakpoint(org.eclipse.debug.core.model.IBreakpoint, |
| * org.eclipse.core.runtime.IAdaptable) |
| */ |
| public void addBreakpoint(IBreakpoint breakpoint, IAdaptable category) { |
| addBreakpoints(new IBreakpoint[]{breakpoint}, category); |
| } |
| |
| /** |
| * Gets the working set names from the marker |
| * |
| * @param marker |
| * them marker to get the names from |
| * @return the listing of markers or an empty String array, never null |
| * |
| * @since 3.2 |
| */ |
| private String[] getWorkingsetAttributeFromMarker(IMarker marker, String type) { |
| try { |
| String name = (String) marker.getAttribute(type); |
| if (name != null) { |
| return name.split("\\" + IImportExportConstants.DELIMITER); //$NON-NLS-1$ |
| } |
| } |
| catch (CoreException e) {DebugPlugin.log(e);} |
| return new String[] {}; |
| } |
| |
| /* |
| * (non-Javadoc) |
| * |
| * @see org.eclipse.debug.ui.IBreakpointOrganizerDelegate#removeBreakpoint(org.eclipse.debug.core.model.IBreakpoint, |
| * org.eclipse.core.runtime.IAdaptable) |
| */ |
| public void removeBreakpoint(IBreakpoint breakpoint, IAdaptable category) { |
| if (category instanceof WorkingSetCategory) { |
| IWorkingSet set = ((WorkingSetCategory) category).getWorkingSet(); |
| IAdaptable[] elements = set.getElements(); |
| List list = new ArrayList(); |
| for (int i = 0; i < elements.length; i++) { |
| IAdaptable adaptable = elements[i]; |
| if (!adaptable.equals(breakpoint)) { |
| list.add(adaptable); |
| } |
| } |
| fCache.removeMappedEntry(breakpoint.getMarker(), set.getName()); |
| fCache.flushMarkerCache(breakpoint.getMarker()); |
| set.setElements((IAdaptable[]) list.toArray(new IAdaptable[list.size()])); |
| } |
| } |
| |
| /* |
| * (non-Javadoc) |
| * |
| * @see org.eclipse.debug.ui.IBreakpointOrganizerDelegate#getCategories() |
| */ |
| public IAdaptable[] getCategories() { |
| IWorkingSet[] workingSets = fWorkingSetManager.getWorkingSets(); |
| List all = new ArrayList(); |
| for (int i = 0; i < workingSets.length; i++) { |
| IWorkingSet set = workingSets[i]; |
| if (IDebugUIConstants.BREAKPOINT_WORKINGSET_ID.equals(set |
| .getId())) { |
| all.add(new WorkingSetCategory(set)); |
| } |
| } |
| return (IAdaptable[]) all.toArray(new IAdaptable[all.size()]); |
| } |
| |
| /* (non-Javadoc) |
| * @see org.eclipse.debug.ui.IBreakpointOrganizerDelegateExtension#addBreakpoints(org.eclipse.debug.core.model.IBreakpoint[], org.eclipse.core.runtime.IAdaptable) |
| */ |
| public void addBreakpoints(IBreakpoint[] breakpoints, IAdaptable category) { |
| if (category instanceof WorkingSetCategory) { |
| IWorkingSet set = ((WorkingSetCategory) category).getWorkingSet(); |
| addBreakpointsToSet(breakpoints, set); |
| } |
| } |
| |
| /* (non-Javadoc) |
| * @see org.eclipse.debug.ui.IBreakpointOrganizerDelegateExtension#removeBreakpoints(org.eclipse.debug.core.model.IBreakpoint[], org.eclipse.core.runtime.IAdaptable) |
| */ |
| public void removeBreakpoints(IBreakpoint[] breakpoints, IAdaptable category) { |
| if (category instanceof WorkingSetCategory) { |
| IWorkingSet set = ((WorkingSetCategory) category).getWorkingSet(); |
| IAdaptable[] elements = set.getElements(); |
| List list = new ArrayList(elements.length); |
| for (int i = 0; i < elements.length; i++) { |
| list.add(elements[i]); |
| } |
| for (int i = 0; i < breakpoints.length; i++) { |
| IBreakpoint breakpoint = breakpoints[i]; |
| fCache.removeMappedEntry(breakpoint.getMarker(), set.getName()); |
| fCache.flushMarkerCache(breakpoint.getMarker()); |
| list.remove(breakpoint); |
| } |
| set.setElements((IAdaptable[]) list.toArray(new IAdaptable[list.size()])); |
| } |
| } |
| } |