1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-04-23 22:52:11 +02:00

[291426] - [breakpoints] Add DSF support for flex-hierarchy breakpoints view.

This commit is contained in:
Pawel Piech 2010-02-11 19:41:37 +00:00
parent 9514e9c398
commit 9d94af8a4d
15 changed files with 1587 additions and 12 deletions

View file

@ -13,13 +13,14 @@ package org.eclipse.cdt.dsf.gdb.internal.ui.viewmodel;
import org.eclipse.cdt.dsf.concurrent.ThreadSafe;
import org.eclipse.cdt.dsf.debug.ui.viewmodel.AbstractDebugVMAdapter;
import org.eclipse.cdt.dsf.debug.ui.viewmodel.SteppingController;
import org.eclipse.cdt.dsf.debug.ui.viewmodel.breakpoints.BreakpointVMProvider;
import org.eclipse.cdt.dsf.debug.ui.viewmodel.expression.ExpressionVMProvider;
import org.eclipse.cdt.dsf.debug.ui.viewmodel.modules.ModulesVMProvider;
import org.eclipse.cdt.dsf.debug.ui.viewmodel.register.RegisterVMProvider;
import org.eclipse.cdt.dsf.debug.ui.viewmodel.variable.VariableVMProvider;
import org.eclipse.cdt.dsf.gdb.internal.ui.viewmodel.launch.LaunchVMProvider;
import org.eclipse.cdt.dsf.service.DsfSession;
import org.eclipse.cdt.dsf.ui.viewmodel.datamodel.AbstractDMVMProvider;
import org.eclipse.cdt.dsf.ui.viewmodel.IVMProvider;
import org.eclipse.debug.internal.ui.viewers.model.provisional.IColumnPresentationFactory;
import org.eclipse.debug.internal.ui.viewers.model.provisional.IPresentationContext;
import org.eclipse.debug.ui.IDebugUIConstants;
@ -43,7 +44,7 @@ public class GdbViewModelAdapter extends AbstractDebugVMAdapter
}
@Override
protected AbstractDMVMProvider createViewModelProvider(IPresentationContext context) {
protected IVMProvider createViewModelProvider(IPresentationContext context) {
if ( IDebugUIConstants.ID_DEBUG_VIEW.equals(context.getId()) ) {
return new LaunchVMProvider(this, context, getSession());
} else if (IDebugUIConstants.ID_VARIABLE_VIEW.equals(context.getId()) ) {
@ -54,6 +55,8 @@ public class GdbViewModelAdapter extends AbstractDebugVMAdapter
return new ExpressionVMProvider(this, context, getSession());
} else if (IDebugUIConstants.ID_MODULE_VIEW.equals(context.getId()) ) {
return new ModulesVMProvider(this, context, getSession());
} else if (IDebugUIConstants.ID_BREAKPOINT_VIEW.equals(context.getId()) ) {
return new BreakpointVMProvider(this, context);
}
return null;
}

View file

@ -29,6 +29,7 @@ Export-Package: org.eclipse.cdt.dsf.debug.internal.ui.disassembly.provisional,
org.eclipse.cdt.dsf.debug.ui.sourcelookup,
org.eclipse.cdt.dsf.debug.ui.viewmodel;x-friends:="org.eclipse.cdt.dsf.gdb.ui,org.eclipse.cdt.examples.dsf,org.eclipse.cdt.examples.dsf.pda.ui",
org.eclipse.cdt.dsf.debug.ui.viewmodel.actions;x-friends:="org.eclipse.cdt.dsf.gdb.ui,org.eclipse.cdt.examples.dsf,org.eclipse.cdt.examples.dsf.pda.ui",
org.eclipse.cdt.dsf.debug.ui.viewmodel.breakpoints;x-friends:="org.eclipse.cdt.dsf.gdb.ui,org.eclipse.cdt.examples.dsf,org.eclipse.cdt.examples.dsf.pda.ui",
org.eclipse.cdt.dsf.debug.ui.viewmodel.expression;x-friends:="org.eclipse.cdt.dsf.gdb.ui,org.eclipse.cdt.examples.dsf,org.eclipse.cdt.examples.dsf.pda.ui",
org.eclipse.cdt.dsf.debug.ui.viewmodel.launch;
x-friends:="org.eclipse.cdt.dsf.gdb.ui,

View file

@ -0,0 +1,74 @@
/*******************************************************************************
* Copyright (c) 2008 Wind River Systems and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Wind River Systems - initial API and implementation
*******************************************************************************/
package org.eclipse.cdt.dsf.debug.ui.viewmodel.breakpoints;
import org.eclipse.cdt.dsf.ui.viewmodel.AbstractVMContext;
import org.eclipse.core.runtime.IAdaptable;
import org.eclipse.debug.core.model.IBreakpoint;
import org.eclipse.debug.internal.ui.breakpoints.provisional.IBreakpointContainer;
import org.eclipse.debug.internal.ui.breakpoints.provisional.IBreakpointOrganizer;
/**
*
*
* @since 2.1
*/
public class BreakpointOrganizerVMContext extends AbstractVMContext implements IBreakpointContainer {
private final IAdaptable fCategory;
private final IBreakpoint[] fBreakpoints;
BreakpointOrganizerVMContext(BreakpointOrganizerVMNode vmNode, IAdaptable category, IBreakpoint[] breakpoints) {
super(vmNode);
fCategory = category;
fBreakpoints = breakpoints;
}
@Override
public boolean equals(Object obj) {
return obj instanceof BreakpointOrganizerVMContext &&
getVMNode().equals( ((BreakpointOrganizerVMContext)obj).getVMNode() ) &&
getOrganizer().equals( ((BreakpointOrganizerVMContext)obj).getOrganizer() ) &&
fCategory.equals(((BreakpointOrganizerVMContext)obj).fCategory);
}
@Override
public int hashCode() {
return getOrganizer().hashCode() + getVMNode().hashCode() + fCategory.hashCode();
}
public IBreakpointOrganizer getOrganizer() {
return ((BreakpointOrganizerVMNode)getVMNode()).getOrganizer();
}
public IAdaptable getCategory() {
return fCategory;
}
public boolean contains(IBreakpoint breakpoint) {
for (IBreakpoint bp : fBreakpoints) {
if (bp.equals(breakpoint)) {
return true;
}
}
return false;
}
public IBreakpoint[] getBreakpoints() {
return fBreakpoints;
}
@Override
public String toString() {
return fCategory.toString();
}
}

View file

@ -0,0 +1,162 @@
/*******************************************************************************
* Copyright (c) 2008 Wind River Systems and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Wind River Systems - initial API and implementation
*******************************************************************************/
package org.eclipse.cdt.dsf.debug.ui.viewmodel.breakpoints;
import java.util.List;
import org.eclipse.cdt.dsf.concurrent.RequestMonitor;
import org.eclipse.cdt.dsf.ui.concurrent.ViewerDataRequestMonitor;
import org.eclipse.cdt.dsf.ui.viewmodel.AbstractVMNode;
import org.eclipse.cdt.dsf.ui.viewmodel.VMDelta;
import org.eclipse.core.runtime.IAdaptable;
import org.eclipse.debug.core.model.IBreakpoint;
import org.eclipse.debug.internal.ui.breakpoints.provisional.IBreakpointOrganizer;
import org.eclipse.debug.internal.ui.breakpoints.provisional.IBreakpointUIConstants;
import org.eclipse.debug.internal.ui.viewers.model.provisional.IChildrenCountUpdate;
import org.eclipse.debug.internal.ui.viewers.model.provisional.IChildrenUpdate;
import org.eclipse.debug.internal.ui.viewers.model.provisional.IHasChildrenUpdate;
import org.eclipse.debug.internal.ui.viewers.model.provisional.IModelDelta;
import org.eclipse.jface.util.IPropertyChangeListener;
import org.eclipse.jface.util.PropertyChangeEvent;
/**
*
*
* @since 2.1
*/
public class BreakpointOrganizerVMNode extends AbstractVMNode {
private final IBreakpointOrganizer fOrganizer;
private final IPropertyChangeListener fOrganizerListener = new IPropertyChangeListener() {
public void propertyChange(PropertyChangeEvent event) {
((BreakpointVMProvider)getVMProvider()).handleEventInExecThread(event);
}
};
public BreakpointOrganizerVMNode(BreakpointVMProvider provider, IBreakpointOrganizer organizer) {
super(provider);
fOrganizer = organizer;
fOrganizer.addPropertyChangeListener(fOrganizerListener);
}
@Override
public void dispose() {
fOrganizer.removePropertyChangeListener(fOrganizerListener);
super.dispose();
}
public IBreakpointOrganizer getOrganizer() {
return fOrganizer;
}
public void update(final IHasChildrenUpdate[] updates) {
for (final IHasChildrenUpdate update : updates) {
if (!checkUpdate(update)) continue;
((BreakpointVMProvider)getVMProvider()).getBreakpointOrganizerVMCs(
this, update.getElementPath(),
new ViewerDataRequestMonitor<List<BreakpointOrganizerVMContext>>(getExecutor(), update) {
@Override
protected void handleCompleted() {
if (isSuccess()) {
update.setHasChilren(!getData().isEmpty());
} else {
update.setHasChilren(false);
}
update.done();
}
});
}
}
public void update(final IChildrenCountUpdate[] updates) {
for (final IChildrenCountUpdate update : updates) {
if (!checkUpdate(update)) continue;
((BreakpointVMProvider)getVMProvider()).getBreakpointOrganizerVMCs(
this, update.getElementPath(),
new ViewerDataRequestMonitor<List<BreakpointOrganizerVMContext>>(getExecutor(), update) {
@Override
protected void handleCompleted() {
if (isSuccess()) {
update.setChildCount(getData().size());
} else {
update.setChildCount(0);
}
update.done();
}
});
}
}
public void update(IChildrenUpdate[] updates) {
for (final IChildrenUpdate update : updates) {
if (!checkUpdate(update)) continue;
((BreakpointVMProvider)getVMProvider()).getBreakpointOrganizerVMCs(
this, update.getElementPath(),
new ViewerDataRequestMonitor<List<BreakpointOrganizerVMContext>>(getExecutor(), update) {
@Override
protected void handleCompleted() {
if (isSuccess()) {
int updateIdx = update.getOffset() != -1 ? update.getOffset() : 0;
int endIdx = updateIdx + (update.getLength() != -1 ? update.getLength() : (getData().size()));
while (updateIdx < endIdx && updateIdx < getData().size()) {
update.setChild(getData().get(updateIdx), updateIdx);
updateIdx++;
}
}
update.done();
}
});
}
}
protected BreakpointOrganizerVMContext createVMContext(IAdaptable category, IBreakpoint[] breakpoints) {
return new BreakpointOrganizerVMContext(this, category, breakpoints);
}
public int getDeltaFlags(Object event) {
if (event instanceof BreakpointsChangedEvent) {
return IModelDelta.CONTENT;
}
else if (BreakpointVMProvider.isPresentationContextEvent(event)) {
PropertyChangeEvent propertyEvent = (PropertyChangeEvent)event;
if (IBreakpointUIConstants.PROP_BREAKPOINTS_FILTER_SELECTION.equals(propertyEvent.getProperty()) ||
IBreakpointUIConstants.PROP_BREAKPOINTS_ELEMENT_COMPARATOR.equals(propertyEvent.getProperty()) ||
IBreakpointUIConstants.PROP_BREAKPOINTS_ORGANIZERS.equals(propertyEvent.getProperty()))
{
return IModelDelta.CONTENT;
}
} else if (BreakpointVMProvider.isBreakpointOrganizerEvent(event)) {
return IModelDelta.CONTENT;
}
return 0;
}
public void buildDelta(Object event, VMDelta parent, int nodeOffset, RequestMonitor requestMonitor) {
if (event instanceof BreakpointsChangedEvent) {
parent.setFlags(parent.getFlags() | IModelDelta.CONTENT);
}
else if (BreakpointVMProvider.isPresentationContextEvent(event)) {
PropertyChangeEvent propertyEvent = (PropertyChangeEvent)event;
if (IBreakpointUIConstants.PROP_BREAKPOINTS_FILTER_SELECTION.equals(propertyEvent.getProperty()) ||
IBreakpointUIConstants.PROP_BREAKPOINTS_ELEMENT_COMPARATOR.equals(propertyEvent.getProperty()) ||
IBreakpointUIConstants.PROP_BREAKPOINTS_ORGANIZERS.equals(propertyEvent.getProperty()))
{
parent.setFlags(parent.getFlags() | IModelDelta.CONTENT);
}
} else if (BreakpointVMProvider.isBreakpointOrganizerEvent(event)) {
parent.setFlags(parent.getFlags() | IModelDelta.CONTENT);
}
requestMonitor.done();
}
}

View file

@ -0,0 +1,57 @@
/*******************************************************************************
* Copyright (c) 2008 Wind River Systems and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Wind River Systems - initial API and implementation
*******************************************************************************/
package org.eclipse.cdt.dsf.debug.ui.viewmodel.breakpoints;
import org.eclipse.cdt.dsf.ui.viewmodel.AbstractVMContext;
import org.eclipse.debug.core.model.IBreakpoint;
/**
* @since 2.1
*/
public class BreakpointVMContext extends AbstractVMContext {
private final IBreakpoint fBreakpoint;
public BreakpointVMContext(BreakpointVMNode node, IBreakpoint breakpoint) {
super(node);
fBreakpoint = breakpoint;
}
public IBreakpoint getBreakpoint() {
return fBreakpoint;
}
@Override
@SuppressWarnings("rawtypes")
public Object getAdapter(Class adapter) {
if (adapter.isInstance(fBreakpoint)) {
return fBreakpoint;
}
return super.getAdapter(adapter);
}
@Override
public boolean equals(Object obj) {
return obj instanceof BreakpointVMContext &&
getBreakpoint().equals( ((BreakpointVMContext)obj).getBreakpoint() ) &&
fBreakpoint.equals(((BreakpointVMContext)obj).fBreakpoint);
}
@Override
public int hashCode() {
return fBreakpoint.hashCode();
}
@Override
public String toString() {
return fBreakpoint.toString();
}
}

View file

@ -0,0 +1,78 @@
/*******************************************************************************
* Copyright (c) 2008 Wind River Systems and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Wind River Systems - initial API and implementation
*******************************************************************************/
package org.eclipse.cdt.dsf.debug.ui.viewmodel.breakpoints;
import org.eclipse.cdt.dsf.datamodel.IDMContext;
import org.eclipse.cdt.dsf.ui.viewmodel.IVMAdapter;
import org.eclipse.cdt.dsf.ui.viewmodel.IVMNode;
import org.eclipse.cdt.dsf.ui.viewmodel.IVMProvider;
import org.eclipse.core.runtime.Platform;
import org.eclipse.core.runtime.PlatformObject;
import org.eclipse.debug.internal.ui.viewers.model.provisional.IElementCompareRequest;
import org.eclipse.debug.internal.ui.viewers.model.provisional.IElementMementoProvider;
import org.eclipse.debug.internal.ui.viewers.model.provisional.IElementMementoRequest;
/**
* @since 2.1
*/
public class BreakpointVMInput extends PlatformObject implements IElementMementoProvider {
private IVMNode fVMNode;
public BreakpointVMInput(IVMNode node, IDMContext activeDMContext) {
fVMNode = node;
}
public void encodeElements(IElementMementoRequest[] requests) {
for (IElementMementoRequest request : requests) {
request.getMemento().putString("ELEMENT_NAME", "BreakpointInputMemento"); //$NON-NLS-1$//$NON-NLS-2$
request.done();
}
}
public void compareElements(IElementCompareRequest[] requests) {
for (IElementCompareRequest request : requests) {
request.setEqual( "BreakpointInputMemento".equals(request.getMemento().getString("ELEMENT_NAME")) ); //$NON-NLS-1$//$NON-NLS-2$
request.done();
}
}
@Override
@SuppressWarnings({"rawtypes" })
public Object getAdapter(Class adapter) {
// If the context implements the given adapter directly, it always takes
// precedence.
if (adapter.isInstance(this)) {
return this;
}
IVMProvider vmProvider = fVMNode.getVMProvider();
IVMAdapter vmAdapter = vmProvider.getVMAdapter();
if (adapter.isInstance(vmAdapter)) {
return vmAdapter;
} else if (adapter.isInstance(vmProvider)) {
return vmProvider;
} else if (adapter.isInstance(fVMNode)) {
return fVMNode;
}
return Platform.getAdapterManager().getAdapter(this, adapter);
}
@Override
public boolean equals(Object obj) {
return obj instanceof BreakpointVMInput;
}
@Override
public int hashCode() {
return getClass().hashCode();
}
}

View file

@ -0,0 +1,60 @@
/*******************************************************************************
* Copyright (c) 2008 Wind River Systems and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Wind River Systems - initial API and implementation
*******************************************************************************/
package org.eclipse.cdt.dsf.debug.ui.viewmodel.breakpoints;
import org.eclipse.cdt.dsf.ui.viewmodel.AbstractVMProvider;
import org.eclipse.cdt.dsf.ui.viewmodel.DefaultVMModelProxyStrategy;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.debug.core.DebugPlugin;
import org.eclipse.debug.core.model.IBreakpoint;
import org.eclipse.debug.internal.ui.breakpoints.provisional.IBreakpointContainer;
import org.eclipse.debug.internal.ui.viewers.model.provisional.ICheckboxModelProxy;
import org.eclipse.debug.internal.ui.viewers.model.provisional.IPresentationContext;
import org.eclipse.jface.viewers.TreePath;
/**
* Breakpoints VM model proxy that includes an ICheckboxModelProxy implementation.
*
* @since 2.1
*/
public class BreakpointVMModelProxyStrategy extends DefaultVMModelProxyStrategy implements ICheckboxModelProxy {
public BreakpointVMModelProxyStrategy(AbstractVMProvider provider, Object rootElement) {
super(provider, rootElement);
}
public boolean setChecked(IPresentationContext context, Object viewerInput, TreePath path, boolean checked) {
Object lastSegment = path.getLastSegment();
if (lastSegment instanceof IBreakpointContainer) {
IBreakpoint[] breakpoints = ((IBreakpointContainer) lastSegment).getBreakpoints();
for (int i = 0; i < breakpoints.length; ++i) {
try {
breakpoints[i].setEnabled(checked);
} catch (CoreException e) {
return false;
}
}
return true;
}
else {
IBreakpoint breakpoint = (IBreakpoint)DebugPlugin.getAdapter(lastSegment, IBreakpoint.class);
if (breakpoint != null) {
try {
breakpoint.setEnabled(checked);
} catch (CoreException e) {
return false;
}
return true;
}
}
return false;
}
}

View file

@ -0,0 +1,322 @@
/*******************************************************************************
* Copyright (c) 2008 Wind River Systems and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Wind River Systems - initial API and implementation
*******************************************************************************/
package org.eclipse.cdt.dsf.debug.ui.viewmodel.breakpoints;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.eclipse.cdt.dsf.concurrent.DataRequestMonitor;
import org.eclipse.cdt.dsf.concurrent.RequestMonitor;
import org.eclipse.cdt.dsf.ui.concurrent.ViewerDataRequestMonitor;
import org.eclipse.cdt.dsf.ui.viewmodel.AbstractVMNode;
import org.eclipse.cdt.dsf.ui.viewmodel.IVMProvider;
import org.eclipse.cdt.dsf.ui.viewmodel.VMChildrenUpdate;
import org.eclipse.cdt.dsf.ui.viewmodel.VMDelta;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.debug.core.model.IBreakpoint;
import org.eclipse.debug.internal.ui.breakpoints.provisional.IBreakpointUIConstants;
import org.eclipse.debug.internal.ui.viewers.model.provisional.ICheckUpdate;
import org.eclipse.debug.internal.ui.viewers.model.provisional.IChildrenCountUpdate;
import org.eclipse.debug.internal.ui.viewers.model.provisional.IChildrenUpdate;
import org.eclipse.debug.internal.ui.viewers.model.provisional.IElementCompareRequest;
import org.eclipse.debug.internal.ui.viewers.model.provisional.IElementLabelProvider;
import org.eclipse.debug.internal.ui.viewers.model.provisional.IElementMementoProvider;
import org.eclipse.debug.internal.ui.viewers.model.provisional.IElementMementoRequest;
import org.eclipse.debug.internal.ui.viewers.model.provisional.IHasChildrenUpdate;
import org.eclipse.debug.internal.ui.viewers.model.provisional.ILabelUpdate;
import org.eclipse.debug.internal.ui.viewers.model.provisional.IModelDelta;
import org.eclipse.debug.internal.ui.viewers.model.provisional.IPresentationContext;
import org.eclipse.jface.resource.ImageDescriptor;
import org.eclipse.jface.util.PropertyChangeEvent;
import org.eclipse.jface.viewers.TreePath;
import org.eclipse.swt.graphics.FontData;
import org.eclipse.swt.graphics.RGB;
import org.eclipse.ui.IMemento;
/**
*
*
* @since 2.1
*/
public class BreakpointVMNode extends AbstractVMNode implements IElementLabelProvider, IElementMementoProvider {
public BreakpointVMNode(IVMProvider provider) {
super(provider);
}
public void update(final IHasChildrenUpdate[] updates) {
for (final IHasChildrenUpdate update : updates) {
if (!checkUpdate(update)) continue;
((BreakpointVMProvider)getVMProvider()).getNestingCategoryBreakpoints(
update.getElementPath(),
new ViewerDataRequestMonitor<IBreakpoint[]>(getExecutor(), update) {
@Override
protected void handleCompleted() {
if (isSuccess()) {
update.setHasChilren(getData().length != 0);
} else {
update.setHasChilren(false);
}
update.done();
}
});
}
}
public void update(final IChildrenCountUpdate[] updates) {
for (final IChildrenCountUpdate update : updates) {
if (!checkUpdate(update)) continue;
((BreakpointVMProvider)getVMProvider()).getNestingCategoryBreakpoints(
update.getElementPath(),
new ViewerDataRequestMonitor<IBreakpoint[]>(getExecutor(), update) {
@Override
protected void handleCompleted() {
if (isSuccess()) {
update.setChildCount(getData().length);
} else {
update.setChildCount(0);
}
update.done();
}
});
}
}
public void update(IChildrenUpdate[] updates) {
for (final IChildrenUpdate update : updates) {
if (!checkUpdate(update)) continue;
((BreakpointVMProvider)getVMProvider()).getNestingCategoryBreakpoints(
update.getElementPath(),
new ViewerDataRequestMonitor<IBreakpoint[]>(getExecutor(), update) {
@Override
protected void handleCompleted() {
if (isSuccess()) {
@SuppressWarnings("unchecked")
Comparator<Object> comparator =
(Comparator<Object>)getVMProvider().getPresentationContext().getProperty(
IBreakpointUIConstants.PROP_BREAKPOINTS_ELEMENT_COMPARATOR);
if (comparator != null) {
Arrays.sort(getData(), comparator);
}
fillUpdateWithBreakpointVMCs(update, getData());
}
update.done();
}
});
}
}
private void fillUpdateWithBreakpointVMCs(IChildrenUpdate update, IBreakpoint[] bps) {
int updateIdx = update.getOffset() != -1 ? update.getOffset() : 0;
int endIdx = updateIdx + (update.getLength() != -1 ? update.getLength() : bps.length);
while (updateIdx < endIdx && updateIdx < bps.length) {
update.setChild(createVMContext(bps[updateIdx]), updateIdx);
updateIdx++;
}
}
protected BreakpointVMContext createVMContext(IBreakpoint bp) {
return new BreakpointVMContext(this, bp);
}
public void update(ILabelUpdate[] updates) {
Map<IElementLabelProvider, List<ILabelUpdate>> delegatesMap = new HashMap<IElementLabelProvider, List<ILabelUpdate>>(1,1);
for (final ILabelUpdate update : updates) {
final IBreakpoint bp = ((BreakpointVMContext)update.getElement()).getBreakpoint();
IElementLabelProvider provider = (IElementLabelProvider)bp.getAdapter(IElementLabelProvider.class);
if (provider == null) {
update.done();
continue;
}
List<ILabelUpdate> delegatesList = delegatesMap.get(provider);
if (delegatesList == null) {
delegatesList = new ArrayList<ILabelUpdate>(updates.length);
delegatesMap.put(provider, delegatesList);
}
delegatesList.add(new ICheckUpdate() {
public void setChecked(boolean checked, boolean grayed) {
if (update instanceof ICheckUpdate) {
((ICheckUpdate)update).setChecked(checked, grayed);
}
}
public String[] getColumnIds() { return update.getColumnIds(); }
public void setLabel(String text, int columnIndex) {
update.setLabel(text, columnIndex);
}
public void setFontData(FontData fontData, int columnIndex) { update.setFontData(fontData, columnIndex); }
public void setImageDescriptor(ImageDescriptor image, int columnIndex) { update.setImageDescriptor(image, columnIndex); }
public void setForeground(RGB foreground, int columnIndex) { update.setForeground(foreground, columnIndex); }
public void setBackground(RGB background, int columnIndex) { update.setBackground(background, columnIndex); }
public IPresentationContext getPresentationContext() { return update.getPresentationContext(); }
public Object getElement() { return bp; }
public TreePath getElementPath() { return update.getElementPath().getParentPath().createChildPath(bp); }
public Object getViewerInput() { return update.getViewerInput(); }
public void setStatus(IStatus status) { update.setStatus(status); }
public IStatus getStatus() { return update.getStatus(); }
public void done() { update.done(); }
public void cancel() { update.cancel(); }
public boolean isCanceled() { return update.isCanceled(); }
});
}
for (IElementLabelProvider provider : delegatesMap.keySet()) {
List<ILabelUpdate> updatesList = delegatesMap.get(provider);
provider.update(updatesList.toArray(new ILabelUpdate[updatesList.size()]));
}
}
public void encodeElements(IElementMementoRequest[] updates) {
Map<IElementMementoProvider, List<IElementMementoRequest>> delegatesMap = new HashMap<IElementMementoProvider, List<IElementMementoRequest>>(1,1);
for (final IElementMementoRequest update : updates) {
final IBreakpoint bp = ((BreakpointVMContext)update.getElement()).getBreakpoint();
IElementMementoProvider provider = (IElementMementoProvider)bp.getAdapter(IElementMementoProvider.class);
if (provider == null) {
update.done();
continue;
}
List<IElementMementoRequest> delegatesList = delegatesMap.get(provider);
if (delegatesList == null) {
delegatesList = new ArrayList<IElementMementoRequest>(updates.length);
delegatesMap.put(provider, delegatesList);
}
delegatesList.add(new IElementMementoRequest() {
public IMemento getMemento() { return update.getMemento(); }
public IPresentationContext getPresentationContext() { return update.getPresentationContext(); }
public Object getElement() { return bp; }
public TreePath getElementPath() { return update.getElementPath().getParentPath().createChildPath(bp); }
public Object getViewerInput() { return update.getViewerInput(); }
public void setStatus(IStatus status) { update.setStatus(status); }
public IStatus getStatus() { return update.getStatus(); }
public void done() { update.done(); }
public void cancel() { update.cancel(); }
public boolean isCanceled() { return update.isCanceled(); }
});
}
for (IElementMementoProvider provider : delegatesMap.keySet()) {
List<IElementMementoRequest> updatesList = delegatesMap.get(provider);
provider.encodeElements(updatesList.toArray(new IElementMementoRequest[updatesList.size()]));
}
}
public void compareElements(IElementCompareRequest[] updates) {
Map<IElementMementoProvider, List<IElementCompareRequest>> delegatesMap = new HashMap<IElementMementoProvider, List<IElementCompareRequest>>(1,1);
for (final IElementCompareRequest update : updates) {
final IBreakpoint bp = ((BreakpointVMContext)update.getElement()).getBreakpoint();
IElementMementoProvider provider = (IElementMementoProvider)bp.getAdapter(IElementMementoProvider.class);
if (provider == null) {
update.done();
continue;
}
List<IElementCompareRequest> delegatesList = delegatesMap.get(provider);
if (delegatesList == null) {
delegatesList = new ArrayList<IElementCompareRequest>(updates.length);
delegatesMap.put(provider, delegatesList);
}
delegatesList.add(new IElementCompareRequest() {
public IMemento getMemento() { return update.getMemento(); }
public void setEqual(boolean equal) { update.setEqual(equal);}
public IPresentationContext getPresentationContext() { return update.getPresentationContext(); }
public Object getElement() { return bp; }
public TreePath getElementPath() { return update.getElementPath().getParentPath().createChildPath(bp); }
public Object getViewerInput() { return update.getViewerInput(); }
public void setStatus(IStatus status) { update.setStatus(status); }
public IStatus getStatus() { return update.getStatus(); }
public void done() { update.done(); }
public void cancel() { update.cancel(); }
public boolean isCanceled() { return update.isCanceled(); }
});
}
for (IElementMementoProvider provider : delegatesMap.keySet()) {
List<IElementCompareRequest> updatesList = delegatesMap.get(provider);
provider.compareElements(updatesList.toArray(new IElementCompareRequest[updatesList.size()]));
}
}
public int getDeltaFlags(Object event) {
if (event instanceof BreakpointsChangedEvent) {
BreakpointsChangedEvent bpChangedEvent = ((BreakpointsChangedEvent)event);
if (BreakpointsChangedEvent.Type.ADDED.equals(bpChangedEvent.getType())) {
return IModelDelta.CONTENT | IModelDelta.SELECT | IModelDelta.EXPAND;
}
return IModelDelta.CONTENT;
}
else if (BreakpointVMProvider.isPresentationContextEvent(event)) {
PropertyChangeEvent propertyEvent = (PropertyChangeEvent)event;
if (IBreakpointUIConstants.PROP_BREAKPOINTS_FILTER_SELECTION.equals(propertyEvent.getProperty()) ||
IBreakpointUIConstants.PROP_BREAKPOINTS_ELEMENT_COMPARATOR.equals(propertyEvent.getProperty()))
{
return IModelDelta.CONTENT;
} else if (IBreakpointUIConstants.PROP_BREAKPOINTS_ORGANIZERS.equals(propertyEvent.getProperty())) {
return IModelDelta.EXPAND | IModelDelta.CONTENT;
}
}
return 0;
}
public void buildDelta(Object event, VMDelta parent, int nodeOffset, RequestMonitor rm) {
if (event instanceof BreakpointsChangedEvent) {
BreakpointsChangedEvent bpChangedEvent = ((BreakpointsChangedEvent)event);
if (BreakpointsChangedEvent.Type.ADDED.equals(bpChangedEvent.getType())) {
buildBreakpointAddedDelta(bpChangedEvent, parent, nodeOffset, rm);
// Do not call rm.done() in this method!
return;
} else {
parent.setFlags(parent.getFlags() | IModelDelta.CONTENT);
}
}
else if (BreakpointVMProvider.isPresentationContextEvent(event)) {
PropertyChangeEvent propertyEvent = (PropertyChangeEvent)event;
if (IBreakpointUIConstants.PROP_BREAKPOINTS_FILTER_SELECTION.equals(propertyEvent.getProperty()) ||
IBreakpointUIConstants.PROP_BREAKPOINTS_ELEMENT_COMPARATOR.equals(propertyEvent.getProperty()))
{
parent.setFlags(parent.getFlags() | IModelDelta.CONTENT);
} else if (IBreakpointUIConstants.PROP_BREAKPOINTS_ORGANIZERS.equals(propertyEvent.getProperty())) {
parent.setFlags(parent.getFlags() | IModelDelta.EXPAND | IModelDelta.CONTENT);
}
}
rm.done();
}
private void buildBreakpointAddedDelta(final BreakpointsChangedEvent event, final VMDelta parent, final int nodeOffset, final RequestMonitor rm) {
getVMProvider().updateNode(this, new VMChildrenUpdate(
parent, getVMProvider().getPresentationContext(), -1, -1,
new DataRequestMonitor<List<Object>>(getExecutor(), rm) {
@Override
protected void handleSuccess() {
for (int i = 0; i < event.getBreakpoints().length; i++) {
int bpIndex = getData().indexOf(event.getBreakpoints()[i]);
if (bpIndex >= 0) {
// Select only the first breakpoint that was added
if (i == 0) {
parent.addNode(getData().get(bpIndex), bpIndex, IModelDelta.SELECT);
}
// For all other added breakpoints, expand the parent.
parent.setFlags(parent.getFlags() | IModelDelta.CONTENT | IModelDelta.EXPAND);
}
}
rm.done();
}
}));
}
}

View file

@ -0,0 +1,358 @@
/*******************************************************************************
* Copyright (c) 2006, 2008 Wind River Systems and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Wind River Systems - initial API and implementation
*******************************************************************************/
package org.eclipse.cdt.dsf.debug.ui.viewmodel.breakpoints;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.eclipse.cdt.dsf.concurrent.DataCache;
import org.eclipse.cdt.dsf.concurrent.DataRequestMonitor;
import org.eclipse.cdt.dsf.concurrent.DsfRunnable;
import org.eclipse.cdt.dsf.concurrent.IDsfStatusConstants;
import org.eclipse.cdt.dsf.concurrent.RequestMonitor;
import org.eclipse.cdt.dsf.datamodel.IDMContext;
import org.eclipse.cdt.dsf.debug.ui.viewmodel.expression.IExpressionVMNode;
import org.eclipse.cdt.dsf.internal.ui.DsfUIPlugin;
import org.eclipse.cdt.dsf.ui.viewmodel.AbstractVMAdapter;
import org.eclipse.cdt.dsf.ui.viewmodel.AbstractVMProvider;
import org.eclipse.cdt.dsf.ui.viewmodel.IRootVMNode;
import org.eclipse.cdt.dsf.ui.viewmodel.IVMModelProxy;
import org.eclipse.cdt.dsf.ui.viewmodel.IVMNode;
import org.eclipse.cdt.dsf.ui.viewmodel.datamodel.IDMVMContext;
import org.eclipse.cdt.dsf.ui.viewmodel.datamodel.RootDMVMNode;
import org.eclipse.core.resources.IMarkerDelta;
import org.eclipse.core.runtime.IAdaptable;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.debug.core.DebugPlugin;
import org.eclipse.debug.core.IBreakpointsListener;
import org.eclipse.debug.core.model.IBreakpoint;
import org.eclipse.debug.internal.ui.breakpoints.provisional.IBreakpointOrganizer;
import org.eclipse.debug.internal.ui.breakpoints.provisional.IBreakpointUIConstants;
import org.eclipse.debug.internal.ui.breakpoints.provisional.OtherBreakpointCategory;
import org.eclipse.debug.internal.ui.viewers.model.provisional.IColumnPresentation;
import org.eclipse.debug.internal.ui.viewers.model.provisional.IModelDelta;
import org.eclipse.debug.internal.ui.viewers.model.provisional.IPresentationContext;
import org.eclipse.debug.internal.ui.viewers.model.provisional.IViewerInputUpdate;
import org.eclipse.debug.ui.IBreakpointOrganizerDelegate;
import org.eclipse.jface.util.IPropertyChangeListener;
import org.eclipse.jface.util.PropertyChangeEvent;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.TreePath;
/**
* The expression provider is used to populate the contents of the expressions
* view. The node hierarchy in this view is a little different than in a typical
* provider: the expression manager node should be registered as the single child
* of the root node and no nodes should be registered as children of expression node.
* Instead the top level expression nodes should be registered with a call to
* {@link #setExpressionNodes(IExpressionVMNode[])}. And each expression node can
* have its own sub-hierarchy of elements as needed. However all nodes configured
* with this provider (with the exception of the root and the expression manager)
* should implement {@link IExpressionVMNode}.
*
* @since 2.1
*/
public class BreakpointVMProvider extends AbstractVMProvider
{
private IPropertyChangeListener fPresentationContextListener = new IPropertyChangeListener() {
public void propertyChange(PropertyChangeEvent event) {
handleEventInExecThread(event);
}
};
private IBreakpointsListener fBreakpointsListener = new IBreakpointsListener() {
public void breakpointsRemoved(IBreakpoint[] breakpoints, IMarkerDelta[] deltas) {
handleEventInExecThread(new BreakpointsChangedEvent(BreakpointsChangedEvent.Type.REMOVED, breakpoints));
}
public void breakpointsChanged(IBreakpoint[] breakpoints, IMarkerDelta[] deltas) {
handleEventInExecThread(new BreakpointsChangedEvent(BreakpointsChangedEvent.Type.CHANGED, breakpoints));
}
public void breakpointsAdded(IBreakpoint[] breakpoints) {
handleEventInExecThread(new BreakpointsChangedEvent(BreakpointsChangedEvent.Type.ADDED, breakpoints));
}
};
private class ContainerBreakpointsCache extends DataCache<List<BreakpointOrganizerVMContext>> {
private BreakpointOrganizerVMNode fOrganizerVMNode;
private TreePath fParentPath;
public ContainerBreakpointsCache(BreakpointOrganizerVMNode organizerVMNode, TreePath parentPath) {
super(getExecutor());
fOrganizerVMNode = organizerVMNode;
fParentPath = parentPath;
}
@Override
protected void retrieve(final DataRequestMonitor<List<BreakpointOrganizerVMContext>> rm) {
getNestingCategoryBreakpoints(
fParentPath,
new DataRequestMonitor<IBreakpoint[]>(getExecutor(), rm) {
@SuppressWarnings({ "cast", "unchecked" })
@Override
protected void handleSuccess() {
Map<IAdaptable, List<IBreakpoint>> bpsLists = new HashMap<IAdaptable, List<IBreakpoint>>();
for (IBreakpoint bp : getData()) {
IAdaptable[] bpCategories = fOrganizerVMNode.getOrganizer().getCategories(bp);
if (bpCategories == null || bpCategories.length == 0) {
bpCategories = OtherBreakpointCategory.getCategories(fOrganizerVMNode.getOrganizer());
}
for (IAdaptable category : bpCategories) {
List<IBreakpoint> categoryBPs = bpsLists.get(category);
if (categoryBPs == null) {
categoryBPs = new ArrayList<IBreakpoint>();
bpsLists.put(category, categoryBPs);
}
categoryBPs.add(bp);
}
}
// Only show the empty containers for the top-level node.
if (fParentPath.getSegmentCount() == 0) {
final IAdaptable[] independentCategories = fOrganizerVMNode.getOrganizer().getCategories();
if (independentCategories != null) {
for (IAdaptable category : independentCategories) {
if (!bpsLists.containsKey(category)) {
bpsLists.put(category, (List<IBreakpoint>)Collections.EMPTY_LIST);
}
}
}
}
List<BreakpointOrganizerVMContext> vmcs = new ArrayList<BreakpointOrganizerVMContext>(bpsLists.size());
for (Map.Entry<IAdaptable, List<IBreakpoint>> entry : bpsLists.entrySet()) {
List<IBreakpoint> bpsList = entry.getValue();
IBreakpoint[] bpsArray = bpsList.toArray(new IBreakpoint[bpsList.size()]);
vmcs.add(createBreakpointOrganizerVMContext(fOrganizerVMNode, entry.getKey(), bpsArray));
}
Comparator<Object> comparator = (Comparator<Object>)getPresentationContext().getProperty(
IBreakpointUIConstants.PROP_BREAKPOINTS_ELEMENT_COMPARATOR);
if (comparator != null) {
Collections.sort(vmcs, comparator);
}
rm.setData(vmcs);
rm.done();
}
});
}
};
private final Map<TreePath, ContainerBreakpointsCache> fContainerBreakpointsCacheMap =
new HashMap<TreePath, ContainerBreakpointsCache>();
private DataCache<IBreakpoint[]> fFilteredBreakpointsCache = new DataCache<IBreakpoint[]>(getExecutor()) {
@Override
protected void retrieve(org.eclipse.cdt.dsf.concurrent.DataRequestMonitor<IBreakpoint[]> rm) {
calcFileteredBreakpoints(rm);
}
};
public BreakpointVMProvider(AbstractVMAdapter adapter, IPresentationContext context) {
super(adapter, context);
configureLayout();
context.addPropertyChangeListener(fPresentationContextListener);
DebugPlugin.getDefault().getBreakpointManager().addBreakpointListener(fBreakpointsListener);
}
@Override
protected IVMModelProxy createModelProxyStrategy(Object rootElement) {
return new BreakpointVMModelProxyStrategy(this, rootElement);
}
protected IVMNode createBreakpointVMNode() {
return new BreakpointVMNode(this);
}
/**
* Configures the nodes of this provider. This method may be over-ridden by
* sub classes to create an alternate configuration in this provider.
*/
protected void configureLayout() {
/*
* Create the top level node which provides the anchor starting point.
*/
IRootVMNode rootNode = new RootDMVMNode(this);
IBreakpointOrganizer[] organizers = (IBreakpointOrganizer[])
getPresentationContext().getProperty(IBreakpointUIConstants.PROP_BREAKPOINTS_ORGANIZERS);
IVMNode parentNode = rootNode;
if (organizers != null) {
for (IBreakpointOrganizer organizer : organizers) {
IVMNode organizerNode = new BreakpointOrganizerVMNode(this, organizer);
addChildNodes(parentNode, new IVMNode[] {organizerNode});
parentNode = organizerNode;
}
}
IVMNode bpsNode = createBreakpointVMNode();
addChildNodes(parentNode, new IVMNode[] {bpsNode});
/*
* Let the work know which is the top level node.
*/
setRootNode(rootNode);
}
@Override
public void dispose() {
getPresentationContext().removePropertyChangeListener(fPresentationContextListener);
DebugPlugin.getDefault().getBreakpointManager().removeBreakpointListener(fBreakpointsListener);
super.dispose();
}
@Override
public IColumnPresentation createColumnPresentation(IPresentationContext context, Object element) {
return null;
}
@Override
public String getColumnPresentationId(IPresentationContext context, Object element) {
return null;
}
@Override
public void update(IViewerInputUpdate update) {
IStructuredSelection filterSelection = (IStructuredSelection)
update.getPresentationContext().getProperty(IBreakpointUIConstants.PROP_BREAKPOINTS_FILTER_SELECTION);
IDMContext activeDMContext = null;
if (filterSelection != null) {
if (update.getElement() instanceof IDMVMContext) {
activeDMContext = ((IDMVMContext)update.getElement()).getDMContext();
}
}
update.setInputElement(new BreakpointVMInput(getRootVMNode(), activeDMContext));
update.done();
}
public void getNestingCategoryBreakpoints(TreePath path, final DataRequestMonitor<IBreakpoint[]> rm) {
BreakpointOrganizerVMContext nestingOrganizerVmc = null;
while (path.getSegmentCount() > 0) {
if (path.getLastSegment() instanceof BreakpointOrganizerVMContext) {
nestingOrganizerVmc = (BreakpointOrganizerVMContext)path.getLastSegment();
break;
}
path = path.getParentPath();
}
if (nestingOrganizerVmc == null) {
getFileteredBreakpoints(rm);
} else {
final BreakpointOrganizerVMContext _nestingOrganizerVmc = nestingOrganizerVmc;
getBreakpointOrganizerVMCs(
(BreakpointOrganizerVMNode)_nestingOrganizerVmc.getVMNode(), path.getParentPath(),
new DataRequestMonitor<List<BreakpointOrganizerVMContext>>(getExecutor(), rm) {
@Override
protected void handleCompleted() {
if (isSuccess()) {
int newVmcIdx = getData().indexOf(_nestingOrganizerVmc);
if (newVmcIdx >= 0) {
rm.setData(getData().get(newVmcIdx).getBreakpoints());
} else {
rm.setStatus(new Status(IStatus.ERROR, DsfUIPlugin.PLUGIN_ID, IDsfStatusConstants.INVALID_HANDLE, "Breakpoint category not found", null)); //$NON-NLS-1$
}
}
rm.done();
}
});
}
}
public void getBreakpointOrganizerVMCs(BreakpointOrganizerVMNode organizerVMNode, TreePath path,
DataRequestMonitor<List<BreakpointOrganizerVMContext>> rm)
{
ContainerBreakpointsCache cache = fContainerBreakpointsCacheMap.get(path);
if (cache == null) {
cache = new ContainerBreakpointsCache(organizerVMNode, path);
fContainerBreakpointsCacheMap.put(path, cache);
}
cache.request(rm);
}
protected BreakpointOrganizerVMContext createBreakpointOrganizerVMContext(BreakpointOrganizerVMNode node, IAdaptable category, IBreakpoint[] breakpoints) {
return new BreakpointOrganizerVMContext(node, category, breakpoints);
}
public void getFileteredBreakpoints(final DataRequestMonitor<IBreakpoint[]> rm) {
fFilteredBreakpointsCache.request(rm);
}
protected void calcFileteredBreakpoints(DataRequestMonitor<IBreakpoint[]> rm) {
rm.setData(DebugPlugin.getDefault().getBreakpointManager().getBreakpoints());
rm.done();
}
public void handleEventInExecThread(final Object event) {
getExecutor().execute(new DsfRunnable() {
public void run() {
handleEvent(event);
}
});
}
@Override
public void handleEvent(Object event, RequestMonitor rm) {
if (isPresentationContextEvent(event)) {
PropertyChangeEvent propertyEvent = (PropertyChangeEvent)event;
if (IBreakpointUIConstants.PROP_BREAKPOINTS_ORGANIZERS.equals(propertyEvent.getProperty()))
{
clearNodes();
configureLayout();
}
}
super.handleEvent(event, rm);
}
public static boolean isPresentationContextEvent(Object event) {
return event instanceof PropertyChangeEvent && ((PropertyChangeEvent)event).getSource() instanceof IPresentationContext;
}
public static boolean isBreakpointOrganizerEvent(Object event) {
return event instanceof PropertyChangeEvent && ((PropertyChangeEvent)event).getSource() instanceof IBreakpointOrganizerDelegate;
}
private static final int MODEL_DELTA_CHANGE_FLAGS = IModelDelta.STATE | IModelDelta.CONTENT | IModelDelta.ADDED | IModelDelta.REMOVED | IModelDelta.REPLACED | IModelDelta.INSERTED;
@Override
protected void handleEvent(IVMModelProxy proxyStrategy, Object event, RequestMonitor rm) {
// Before generating a delta, flush the caches.
int deltaFlags = proxyStrategy.getEventDeltaFlags(event);
if ((deltaFlags & MODEL_DELTA_CHANGE_FLAGS) != 0) {
flushCaches();
}
super.handleEvent(proxyStrategy, event, rm);
}
private void flushCaches() {
fFilteredBreakpointsCache.reset();
for (DataCache<?> cache : fContainerBreakpointsCacheMap.values()) {
cache.reset();
}
fContainerBreakpointsCacheMap.clear();
}
}

View file

@ -0,0 +1,36 @@
/*******************************************************************************
* Copyright (c) 2008 Wind River Systems and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Wind River Systems - initial API and implementation
*******************************************************************************/
package org.eclipse.cdt.dsf.debug.ui.viewmodel.breakpoints;
import org.eclipse.debug.core.model.IBreakpoint;
/**
* @since 2.1
*/
public class BreakpointsChangedEvent {
public enum Type { ADDED, REMOVED, CHANGED };
private final Type fType;
private final IBreakpoint[] fBreakpoints;
public BreakpointsChangedEvent(Type type, IBreakpoint[] breakpoints) {
fType = type;
fBreakpoints = breakpoints;
}
public Type getType() {
return fType;
}
public IBreakpoint[] getBreakpoints() {
return fBreakpoints;
}
}

View file

@ -0,0 +1,181 @@
/*******************************************************************************
* Copyright (c) 2008 Wind River Systems and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Wind River Systems - initial API and implementation
*******************************************************************************/
package org.eclipse.cdt.dsf.debug.ui.viewmodel.breakpoints;
import java.util.Arrays;
import java.util.Comparator;
import java.util.List;
import org.eclipse.cdt.dsf.concurrent.DataRequestMonitor;
import org.eclipse.cdt.dsf.concurrent.RequestMonitor;
import org.eclipse.cdt.dsf.ui.concurrent.ViewerDataRequestMonitor;
import org.eclipse.cdt.dsf.ui.viewmodel.AbstractVMNode;
import org.eclipse.cdt.dsf.ui.viewmodel.IVMProvider;
import org.eclipse.cdt.dsf.ui.viewmodel.VMChildrenUpdate;
import org.eclipse.cdt.dsf.ui.viewmodel.VMDelta;
import org.eclipse.debug.core.model.IBreakpoint;
import org.eclipse.debug.internal.ui.breakpoints.provisional.IBreakpointUIConstants;
import org.eclipse.debug.internal.ui.viewers.model.provisional.IChildrenCountUpdate;
import org.eclipse.debug.internal.ui.viewers.model.provisional.IChildrenUpdate;
import org.eclipse.debug.internal.ui.viewers.model.provisional.IHasChildrenUpdate;
import org.eclipse.debug.internal.ui.viewers.model.provisional.IModelDelta;
import org.eclipse.jface.util.PropertyChangeEvent;
/**
*
*
* @since 2.1
*/
public class RawBreakpointVMNode extends AbstractVMNode {
public RawBreakpointVMNode(IVMProvider provider) {
super(provider);
}
public void update(final IHasChildrenUpdate[] updates) {
for (final IHasChildrenUpdate update : updates) {
if (!checkUpdate(update)) continue;
((BreakpointVMProvider)getVMProvider()).getNestingCategoryBreakpoints(
update.getElementPath(),
new ViewerDataRequestMonitor<IBreakpoint[]>(getExecutor(), update) {
@Override
protected void handleCompleted() {
if (isSuccess()) {
update.setHasChilren(getData().length != 0);
} else {
update.setHasChilren(false);
}
update.done();
}
});
}
}
public void update(final IChildrenCountUpdate[] updates) {
for (final IChildrenCountUpdate update : updates) {
if (!checkUpdate(update)) continue;
((BreakpointVMProvider)getVMProvider()).getNestingCategoryBreakpoints(
update.getElementPath(),
new ViewerDataRequestMonitor<IBreakpoint[]>(getExecutor(), update) {
@Override
protected void handleCompleted() {
if (isSuccess()) {
update.setChildCount(getData().length);
} else {
update.setChildCount(0);
}
update.done();
}
});
}
}
public void update(IChildrenUpdate[] updates) {
for (final IChildrenUpdate update : updates) {
if (!checkUpdate(update)) continue;
((BreakpointVMProvider)getVMProvider()).getNestingCategoryBreakpoints(
update.getElementPath(),
new ViewerDataRequestMonitor<IBreakpoint[]>(getExecutor(), update) {
@Override
protected void handleCompleted() {
if (isSuccess()) {
@SuppressWarnings("unchecked")
Comparator<Object> comparator =
(Comparator<Object>)getVMProvider().getPresentationContext().getProperty(
IBreakpointUIConstants.PROP_BREAKPOINTS_ELEMENT_COMPARATOR);
if (comparator != null) {
Arrays.sort(getData(), comparator);
}
fillUpdateWithBreakpoints(update, getData());
}
update.done();
}
});
}
}
private void fillUpdateWithBreakpoints(IChildrenUpdate update, IBreakpoint[] bps) {
int updateIdx = update.getOffset() != -1 ? update.getOffset() : 0;
int endIdx = updateIdx + (update.getLength() != -1 ? update.getLength() : bps.length);
while (updateIdx < endIdx && updateIdx < bps.length) {
update.setChild(bps[updateIdx], updateIdx);
updateIdx++;
}
}
public int getDeltaFlags(Object event) {
if (event instanceof BreakpointsChangedEvent) {
BreakpointsChangedEvent bpChangedEvent = ((BreakpointsChangedEvent)event);
if (BreakpointsChangedEvent.Type.ADDED.equals(bpChangedEvent.getType())) {
return IModelDelta.CONTENT | IModelDelta.SELECT | IModelDelta.EXPAND;
}
return IModelDelta.CONTENT;
}
else if (BreakpointVMProvider.isPresentationContextEvent(event)) {
PropertyChangeEvent propertyEvent = (PropertyChangeEvent)event;
if (IBreakpointUIConstants.PROP_BREAKPOINTS_FILTER_SELECTION.equals(propertyEvent.getProperty()) ||
IBreakpointUIConstants.PROP_BREAKPOINTS_ELEMENT_COMPARATOR.equals(propertyEvent.getProperty()))
{
return IModelDelta.CONTENT;
} else if (IBreakpointUIConstants.PROP_BREAKPOINTS_ORGANIZERS.equals(propertyEvent.getProperty())) {
return IModelDelta.EXPAND | IModelDelta.CONTENT;
}
}
return 0;
}
public void buildDelta(Object event, VMDelta parent, int nodeOffset, RequestMonitor rm) {
if (event instanceof BreakpointsChangedEvent) {
BreakpointsChangedEvent bpChangedEvent = ((BreakpointsChangedEvent)event);
if (BreakpointsChangedEvent.Type.ADDED.equals(bpChangedEvent.getType())) {
buildBreakpointAddedDelta(bpChangedEvent, parent, nodeOffset, rm);
// Do not call rm.done() in this method!
return;
} else {
parent.setFlags(parent.getFlags() | IModelDelta.CONTENT);
}
}
else if (BreakpointVMProvider.isPresentationContextEvent(event)) {
PropertyChangeEvent propertyEvent = (PropertyChangeEvent)event;
if (IBreakpointUIConstants.PROP_BREAKPOINTS_FILTER_SELECTION.equals(propertyEvent.getProperty()) ||
IBreakpointUIConstants.PROP_BREAKPOINTS_ELEMENT_COMPARATOR.equals(propertyEvent.getProperty()))
{
parent.setFlags(parent.getFlags() | IModelDelta.CONTENT);
} else if (IBreakpointUIConstants.PROP_BREAKPOINTS_ORGANIZERS.equals(propertyEvent.getProperty())) {
parent.setFlags(parent.getFlags() | IModelDelta.EXPAND | IModelDelta.CONTENT);
}
}
rm.done();
}
private void buildBreakpointAddedDelta(final BreakpointsChangedEvent event, final VMDelta parent, final int nodeOffset, final RequestMonitor rm) {
getVMProvider().updateNode(this, new VMChildrenUpdate(
parent, getVMProvider().getPresentationContext(), -1, -1,
new DataRequestMonitor<List<Object>>(getExecutor(), rm) {
@Override
protected void handleSuccess() {
for (int i = 0; i < event.getBreakpoints().length; i++) {
int bpIndex = getData().indexOf(event.getBreakpoints()[i]);
if (bpIndex >= 0) {
// Select only the first breakpoint that was added
if (i == 0) {
parent.addNode(getData().get(bpIndex), bpIndex, IModelDelta.SELECT);
}
// For all other added breakpoints, expand the parent.
parent.setFlags(parent.getFlags() | IModelDelta.CONTENT | IModelDelta.EXPAND);
}
}
rm.done();
}
}));
}
}

View file

@ -387,13 +387,12 @@ public class DefaultVMContentProviderStrategy implements IElementContentProvider
/**
* Convenience method which checks whether given layout node is a node that
* is configured in this ViewModelProvider.
* <br>
* Note: isOurNode() will also return true if the given node was previously
* configured in the VM provider but was later disposed.
*/
private boolean isOurNode(IVMNode node) {
for (IVMNode nodeToSearch : getVMProvider().getAllVMNodes()) {
if (nodeToSearch.equals(node))
return true;
}
return false;
return node.getVMProvider() == getVMProvider();
}
}

View file

@ -27,6 +27,7 @@ import org.eclipse.core.runtime.SafeRunner;
import org.eclipse.debug.internal.ui.DebugUIPlugin;
import org.eclipse.debug.internal.ui.viewers.model.provisional.IModelChangedListener;
import org.eclipse.debug.internal.ui.viewers.model.provisional.IModelDelta;
import org.eclipse.debug.internal.ui.viewers.model.provisional.IModelDeltaVisitor;
import org.eclipse.debug.internal.ui.viewers.model.provisional.IModelProxy;
import org.eclipse.debug.internal.ui.viewers.model.provisional.IPresentationContext;
import org.eclipse.debug.internal.ui.viewers.model.provisional.ModelDelta;
@ -72,10 +73,17 @@ public class DefaultVMModelProxyStrategy implements IVMModelProxy {
}
public boolean isDeltaEvent(Object event) {
return getEventDeltaFlags(event) != IModelDelta.NO_CHANGE;
}
public int getEventDeltaFlags(Object event) {
IRootVMNode rootNode = getVMProvider().getRootVMNode();
return rootNode != null &&
rootNode.isDeltaEvent(getRootElement(), event) &&
getDeltaFlags(rootNode, null, event) != IModelDelta.NO_CHANGE;
if (rootNode != null &&
rootNode.isDeltaEvent(getRootElement(), event))
{
return getDeltaFlags(rootNode, null, event);
}
return IModelDelta.NO_CHANGE;
}
@ -346,7 +354,9 @@ public class DefaultVMModelProxyStrategy implements IVMModelProxy {
new RequestMonitor(getVMProvider().getExecutor(), rm) {
@Override
protected void handleSuccess() {
rm.setData(viewRootDelta);
// Get rid of redundant CONTENT and STATE flags in delta and prune
// nodes without flags
rm.setData(pruneDelta((VMDelta)viewRootDelta));
rm.done();
}
});
@ -354,6 +364,25 @@ public class DefaultVMModelProxyStrategy implements IVMModelProxy {
});
}
protected VMDelta pruneDelta(VMDelta delta) {
delta.accept(new IModelDeltaVisitor() {
public boolean visit(IModelDelta deltaNode, int depth) {
if ((deltaNode.getFlags() & (IModelDelta.CONTENT | IModelDelta.STATE)) != 0) {
VMDelta parent = (VMDelta)deltaNode.getParentDelta();
while (parent != null) {
if ((parent.getFlags() & IModelDelta.CONTENT) != 0) {
((VMDelta)deltaNode).setFlags(deltaNode.getFlags() & ~(IModelDelta.CONTENT | IModelDelta.STATE));
break;
}
parent = parent.getParentDelta();
}
}
return true;
}
});
return delta;
}
/**
* Base implementation that handles calling child nodes to build
* the model delta. This method delegates to two other methods:

View file

@ -35,7 +35,11 @@ public interface IVMModelProxy extends IModelProxy {
/**
* Returns whether the given event applies to the root element and the
* nodes in this model proxy.
* nodes in this model proxy.
* <p>
* This method is the equivalent of calling
* <code> getEventDeltaFlags(event) != IModelDelta.NO_CHANGE </code>.
* </p>
*/
public boolean isDeltaEvent(Object event);
@ -71,4 +75,15 @@ public interface IVMModelProxy extends IModelProxy {
* @since 2.0
*/
public TreePath getRootPath();
/**
* Returns the delta flags associated with this event. This method is
*
* @param event
* @return
*
* @since 2.1
*/
public int getEventDeltaFlags(Object event);
}

View file

@ -0,0 +1,200 @@
package org.eclipse.cdt.dsf.concurrent;
/*******************************************************************************
* Copyright (c) 2008 Wind River Systems, Inc. and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Wind River Systems - initial API and implementation
*******************************************************************************/
import java.util.LinkedList;
import java.util.List;
import java.util.concurrent.Executor;
import org.eclipse.cdt.dsf.internal.DsfPlugin;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
/**
* A general purpose cache, which caches the result of a single request.
* Sub classes need to implement {@link #retrieve(DataRequestMonitor)} to fetch
* data from the data source. Clients are responsible for calling
* {@link #disable()} and {@link #reset()} to manage the state of the cache in
* response to events from the data source.
* <p>
* This cache requires an executor to use. The executor is used to synchronize
* access to the cache state and data.
* </p>
* @since 2.1
*/
@ConfinedToDsfExecutor("fExecutor")
public abstract class DataCache<V> {
final private Executor fExecutor;
private boolean fValid;
protected DataRequestMonitor<V> fRm;
private V fData;
private IStatus fStatus;
private List<DataRequestMonitor<V>> fWaitingList = new LinkedList<DataRequestMonitor<V>>();
public DataCache(Executor executor) {
fExecutor = executor;
}
/**
* Sub-classes should override this method to retrieve the cache data
* from its source.
*
* @param rm Request monitor for completion of data retrieval.
*/
protected abstract void retrieve(DataRequestMonitor<V> rm);
/**
* Returns <code>true</code> if the cache is currently valid. I.e.
* whether the cache can return a value immediately without first
* retrieving it from the data source.
*/
public boolean isValid() {
return fValid;
}
/**
* Returns <code>true</code> if the cache is currently waiting for data
* from the data source.
*/
public boolean isPending() {
return fRm != null;
}
/**
* Returns the current data value held by this cache. Clients should first
* call isValid() to determine if the data is up to date.
*/
public V getData() {
return fData;
}
/**
* Returns the status of the source request held by this cache. Clients
* should first call isValid() to determine if the data is up to date.
*/
public IStatus getStatus() {
return fStatus;
}
/**
* Request data from the cache. The cache is valid, it will complete the
* request immediately, otherwise data will first be retrieved from the
* source.
* @param req
*/
public void request(final DataRequestMonitor<V> rm) {
if (!fValid) {
boolean first = fWaitingList.isEmpty();
fWaitingList.add(rm);
if(first) {
fRm = new DataRequestMonitor<V>(fExecutor, null) {
@Override
protected void handleCompleted() {
if (!isCanceled()) {
fValid = true;
fRm = null;
set(getData(), getStatus());
}
}
};
retrieve(fRm);
}
} else {
rm.setData(fData);
rm.setStatus(fStatus);
rm.done();
}
}
private void set(V data, IStatus status) {
fData = data;
fStatus = status;
List<DataRequestMonitor<V>> waitingList = fWaitingList;
fWaitingList = new LinkedList<DataRequestMonitor<V>>();
for (DataRequestMonitor<V> rm : waitingList) {
rm.setData(data);
rm.setStatus(status);
rm.done();
}
}
/**
* Resets the cache with a data value <code>null</code> and an error
* status with code {@link IDsfStatusConstants#INVALID_STATE}.
*
* @see #reset(Object, IStatus)
*/
public void reset() {
reset(null, new Status(IStatus.ERROR, DsfPlugin.PLUGIN_ID, IDsfStatusConstants.INVALID_STATE, "Cache reset", null)); //$NON-NLS-1$
}
/**
* Resets the cache with given data and status. Resetting the cache
* forces the cache to be invalid and cancels any current pending requests
* from data source.
* <p>
* This method should be called when the data source has issued an event
* indicating that the source data has changed but data may still be
* retrieved. Clients may need to re-request data following cache reset.
* </p>
* @param data The data that should be returned to any clients currently
* waiting for cache data.
* @status The status that should be returned to any clients currently
* waiting for cache data.
*/
public void reset(V data, IStatus status) {
fValid = false;
if (fRm != null) {
fRm.cancel();
fRm = null;
}
set(data, status);
}
/**
* Disables the cache with a data value <code>null</code> and an error
* status with code {@link IDsfStatusConstants#INVALID_STATE}.
*
* @see #disable(Object, IStatus)
*/
public void disable() {
disable(null, new Status(IStatus.ERROR, DsfPlugin.PLUGIN_ID, IDsfStatusConstants.INVALID_STATE, "Cache disable", null)); //$NON-NLS-1$
}
/**
* Resets the cache then disables it. When a cache is disabled it means
* that it is valid and requests to the data source will not be sent.
* <p>
* This method should be called when the data source has issued an event
* indicating that the source data has changed and future requests for
* data will return the given data and status. Once the source data
* becomes available again, clients should call {@link #reset()}.
* </p>
* @param data The data that should be returned to any clients waiting for
* cache data and for clients requesting data until the cache is reset again.
* @status The status that should be returned to any clients waiting for
* cache data and for clients requesting data until the cache is reset again.
*
* @see #reset(Object, IStatus)
*/
public void disable(V data, IStatus status) {
reset(data, status);
fValid = true;
}
}