1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-04-29 19:45:01 +02:00

Added expression view model implementation (bug 185635).

This commit is contained in:
Pawel Piech 2007-05-05 00:12:37 +00:00
parent da03d03830
commit 810d315bbf
41 changed files with 2351 additions and 281 deletions

View file

@ -2,7 +2,7 @@ Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: Debug Services Framework Debug UI
Bundle-Vendor: Eclipse.org
Bundle-SymbolicName: org.eclipse.dd.dsf.debug.ui
Bundle-SymbolicName: org.eclipse.dd.dsf.debug.ui; singleton:=true
Bundle-Version: 0.9.0.qualifier
Bundle-Activator: org.eclipse.dd.dsf.debug.ui.DsfDebugUIPlugin
Bundle-Localization: plugin
@ -17,7 +17,10 @@ Require-Bundle: org.eclipse.ui,
org.eclipse.dd.dsf.debug
Eclipse-LazyStart: true
Export-Package:
org.eclipse.dd.dsf.debug.ui,
org.eclipse.dd.dsf.debug.ui.viewmodel,
org.eclipse.dd.dsf.debug.ui.viewmodel.expression,
org.eclipse.dd.dsf.debug.ui.viewmodel.launch,
org.eclipse.dd.dsf.debug.ui.viewmodel.register,
org.eclipse.dd.dsf.debug.ui.viewmodel.launch
org.eclipse.dd.dsf.debug.ui.viewmodel.variable
Bundle-RequiredExecutionEnvironment: J2SE-1.5

View file

@ -1,5 +1,10 @@
<?xml version="1.0" encoding="UTF-8"?>
<?eclipse version="3.2"?>
<plugin>
<extension point="org.eclipse.debug.core.watchExpressionDelegates">
<watchExpressionDelegate
debugModel="org.eclipse.dd.dsf.debug.ui"
delegateClass="org.eclipse.dd.dsf.debug.ui.viewmodel.expression.WatchExpressionDelegate"/>
</extension>
</plugin>

View file

@ -20,8 +20,6 @@ import org.eclipse.dd.dsf.ui.viewmodel.IVMRootLayoutNode;
import org.eclipse.dd.dsf.ui.viewmodel.dm.AbstractDMVMLayoutNode.DMVMContext;
import org.eclipse.debug.internal.ui.viewers.model.provisional.IModelDelta;
import org.eclipse.debug.ui.DebugUITools;
import org.eclipse.debug.ui.contexts.DebugContextEvent;
import org.eclipse.debug.ui.contexts.IDebugContextListener;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.ui.IWorkbenchWindow;
@ -39,25 +37,14 @@ import org.eclipse.ui.IWorkbenchWindow;
*/
@SuppressWarnings("restriction")
public class DebugViewSelectionRootLayoutNode extends AbstractVMRootLayoutNode
implements IVMRootLayoutNode, IDebugContextListener
implements IVMRootLayoutNode
{
private ISelection fSelection;
private final IWorkbenchWindow fWindow;
public DebugViewSelectionRootLayoutNode(AbstractVMProvider provider) {
super(provider);
IWorkbenchWindow activeWindow = DsfDebugUIPlugin.getDefault().getWorkbench().getActiveWorkbenchWindow();
if (activeWindow != null) {
fSelection = DebugUITools.getDebugContextManager().getContextService(activeWindow).getActiveContext();
}
DebugUITools.getDebugContextManager().addDebugContextListener(this);
fWindow = DsfDebugUIPlugin.getDefault().getWorkbench().getActiveWorkbenchWindow();
}
@Override
public void dispose() {
DebugUITools.getDebugContextManager().removeDebugContextListener(this);
super.dispose();
}
/**
* If the input object is a Data Model context, and the event is a DMC event.
* Then we can filter the event to make sure that the view does not
@ -109,22 +96,19 @@ public class DebugViewSelectionRootLayoutNode extends AbstractVMRootLayoutNode
* @return
*/
public ISelection getSelection() {
return fSelection;
return DebugUITools.getDebugContextManager().getContextService(fWindow).getActiveContext();
}
public Object getRootObject() {
if (fSelection instanceof IStructuredSelection) {
return ((IStructuredSelection)fSelection).getFirstElement();
ISelection selection = getSelection();
if (selection instanceof IStructuredSelection) {
return ((IStructuredSelection)selection).getFirstElement();
}
return null;
}
public void debugContextChanged(DebugContextEvent event) {
fSelection = event.getContext();
}
private IDMContext<?> getSelectedDMC() {
Object selection = fSelection;
Object selection = getSelection();
if (selection instanceof IStructuredSelection) {
IStructuredSelection structSelection = (IStructuredSelection)selection;
if (structSelection.getFirstElement() instanceof DMVMContext)

View file

@ -0,0 +1,13 @@
package org.eclipse.dd.dsf.debug.ui.viewmodel;
import org.eclipse.dd.dsf.debug.ui.DsfDebugUIPlugin;
public interface IDebugVMConstants {
public static final String ID = DsfDebugUIPlugin.PLUGIN_ID + ".VARIABLES_COLUMN_PRESENTATION_ID"; //$NON-NLS-1$
public static final String COLUMN_ID__NAME = DsfDebugUIPlugin.PLUGIN_ID + ".COLUMN_ID__NAME"; //$NON-NLS-1$
public static final String COLUMN_ID__TYPE = DsfDebugUIPlugin.PLUGIN_ID + ".COLUMN_ID__TYPE"; //$NON-NLS-1$
public static final String COLUMN_ID__VALUE = DsfDebugUIPlugin.PLUGIN_ID + ".COLUMN_ID__VALUE"; //$NON-NLS-1$
public static final String COLUMN_ID__DESCRIPTION = DsfDebugUIPlugin.PLUGIN_ID + ".COLUMN_ID__DESCRIPTION"; //$NON-NLS-1$
public static final String COLUMN_ID__EXPRESSION = DsfDebugUIPlugin.PLUGIN_ID + ".COLUMN_ID__EXPRESSION"; //$NON-NLS-1$
}

View file

@ -0,0 +1,20 @@
/*******************************************************************************
* Copyright (c) 2006 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.dd.dsf.debug.ui.viewmodel;
/**
*
*/
public interface IFormattedValuePreferenceStore {
public String getDefaultFormatId();
public void setDefaultFormatId(String id);
}

View file

@ -0,0 +1,20 @@
/*******************************************************************************
* Copyright (c) 2006 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.dd.dsf.debug.ui.viewmodel;
import org.eclipse.dd.dsf.ui.viewmodel.IVMContext;
/**
*
*/
public interface IFormattedValueVMContext extends IVMContext {
IFormattedValuePreferenceStore getPreferenceStore();
}

View file

@ -0,0 +1,47 @@
/*******************************************************************************
* Copyright (c) 2006 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.dd.dsf.debug.ui.viewmodel;
import org.eclipse.dd.dsf.debug.service.IFormattedValues;
import org.eclipse.jface.action.IAction;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.ui.IViewActionDelegate;
import org.eclipse.ui.IViewPart;
/**
*
*/
public class SetDefaultFormatDecimal implements IViewActionDelegate {
private IFormattedValueVMContext fFormattedValueVMC;
public void init(IViewPart view) {
}
public void run(IAction action) {
if (fFormattedValueVMC != null) {
fFormattedValueVMC.getPreferenceStore().setDefaultFormatId(IFormattedValues.NATURAL_FORMAT);
}
}
public void selectionChanged(IAction action, ISelection selection) {
fFormattedValueVMC = null;
if (selection instanceof IStructuredSelection) {
Object element = ((IStructuredSelection)selection).getFirstElement();
if (element instanceof IFormattedValueVMContext) {
fFormattedValueVMC = ((IFormattedValueVMContext)element);
}
}
action.setEnabled(fFormattedValueVMC != null);
}
}

View file

@ -0,0 +1,52 @@
/*******************************************************************************
* Copyright (c) 2006 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.dd.dsf.debug.ui.viewmodel;
import org.eclipse.core.runtime.IAdaptable;
import org.eclipse.dd.dsf.debug.service.IFormattedValues;
import org.eclipse.dd.dsf.ui.viewmodel.IVMAdapter;
import org.eclipse.dd.dsf.ui.viewmodel.IVMContext;
import org.eclipse.debug.internal.ui.viewers.model.provisional.IElementContentProvider;
import org.eclipse.debug.ui.AbstractDebugView;
import org.eclipse.jface.action.IAction;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.ui.IViewActionDelegate;
import org.eclipse.ui.IViewPart;
/**
*
*/
public class SetDefaultFormatHex implements IViewActionDelegate {
private IFormattedValueVMContext fFormattedValueVMC;
public void init(IViewPart view) {
}
public void run(IAction action) {
if (fFormattedValueVMC != null) {
fFormattedValueVMC.getPreferenceStore().setDefaultFormatId(IFormattedValues.HEX_FORMAT);
}
}
public void selectionChanged(IAction action, ISelection selection) {
fFormattedValueVMC = null;
if (selection instanceof IStructuredSelection) {
Object element = ((IStructuredSelection)selection).getFirstElement();
if (element instanceof IFormattedValueVMContext) {
fFormattedValueVMC = ((IFormattedValueVMContext)element);
}
}
action.setEnabled(fFormattedValueVMC != null);
}
}

View file

@ -0,0 +1,310 @@
/*******************************************************************************
* Copyright (c) 2007 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.dd.dsf.debug.ui.viewmodel.expression;
import java.util.List;
import java.util.Map;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.dd.dsf.concurrent.ConfinedToDsfExecutor;
import org.eclipse.dd.dsf.concurrent.CountingRequestMonitor;
import org.eclipse.dd.dsf.concurrent.DataRequestMonitor;
import org.eclipse.dd.dsf.concurrent.MultiRequestMonitor;
import org.eclipse.dd.dsf.concurrent.RequestMonitor;
import org.eclipse.dd.dsf.datamodel.IDMContext;
import org.eclipse.dd.dsf.datamodel.IDMData;
import org.eclipse.dd.dsf.debug.ui.DsfDebugUIPlugin;
import org.eclipse.dd.dsf.service.DsfSession;
import org.eclipse.dd.dsf.service.IDsfService;
import org.eclipse.dd.dsf.ui.viewmodel.AbstractVMProvider;
import org.eclipse.dd.dsf.ui.viewmodel.IVMLayoutNode;
import org.eclipse.dd.dsf.ui.viewmodel.VMDelta;
import org.eclipse.dd.dsf.ui.viewmodel.VMElementsUpdate;
import org.eclipse.dd.dsf.ui.viewmodel.dm.AbstractDMVMLayoutNode;
import org.eclipse.debug.core.model.IExpression;
import org.eclipse.debug.internal.ui.viewers.model.provisional.IChildrenUpdate;
import org.eclipse.debug.internal.ui.viewers.model.provisional.IModelDelta;
import org.eclipse.jface.viewers.TreePath;
/**
*
*/
@SuppressWarnings("restriction")
public abstract class AbstractExpressionLayoutNode<V extends IDMData> extends AbstractDMVMLayoutNode<V>
implements IExpressionLayoutNode
{
public AbstractExpressionLayoutNode(AbstractVMProvider provider, DsfSession session, Class<? extends IDMContext<V>> dmcClassType) {
super(provider, session, dmcClassType);
}
public void getElementForExpression(final IChildrenUpdate update, final String expressionText, final IExpression expression) {
final int exprLength = getExpressionLength(expressionText);
if (exprLength < 0) {
update.setStatus(new Status(IStatus.ERROR, DsfDebugUIPlugin.PLUGIN_ID, IDsfService.INTERNAL_ERROR, "Invalid expression", null)); //$NON-NLS-1$
update.done();
return;
}
final String nodeExpressionText = exprLength > 0 ? expressionText.substring(0, exprLength) : expressionText;
getElementForExpressionPart(
update, nodeExpressionText,
new DataRequestMonitor<Object>(getExecutor(), null) {
@Override
protected void handleOK() {
/**
* If the current expression is the whole expression from the argument,
* return the VMC. Otherwise, call the child nodes to continue evaluating
* the expression.
*/
if (exprLength == expressionText.length()) {
Object element = getData();
associateExpression(element, expression);
update.setChild(element, 0);
update.done();
} else {
getVMContextForExpressionFromChildNodes(
update, getData(), expressionText.substring(exprLength), expression);
}
}
@Override
protected void handleErrorOrCancel() {
update.setStatus(getStatus());
update.done();
}
});
}
protected void getElementForExpressionPart(final IChildrenUpdate update, final String expressionPartText, final DataRequestMonitor<Object> rm) {
updateElements(new VMElementsUpdate(
update, -1, -1,
new DataRequestMonitor<List<Object>>(getSession().getExecutor(), rm) {
@Override
protected void handleOK() {
if (getData().size() == 0) {
rm.setStatus(new Status(IStatus.ERROR, DsfDebugUIPlugin.PLUGIN_ID, IDsfService.INTERNAL_ERROR, "No contexts", null)); //$NON-NLS-1$
rm.done();
} else {
final List<Object> elements = getData();
final MultiRequestMonitor<DataRequestMonitor<Boolean>> multiRm = new MultiRequestMonitor<DataRequestMonitor<Boolean>>(getExecutor(), rm) {
@Override
protected void handleOK() {
boolean foundMatchingContext = false;
for (int i = 0; i < getRequestMonitors().size(); i++) {
if (getRequestMonitors().get(i).getData()) {
rm.setData(elements.get(i));
foundMatchingContext = true;
break;
}
}
if (!foundMatchingContext) {
rm.setStatus(new Status(IStatus.ERROR, DsfDebugUIPlugin.PLUGIN_ID, IDsfService.INTERNAL_ERROR, "Context not found", null)); //$NON-NLS-1$
}
rm.done();
}
};
for (Object element : elements) {
testContextForExpression(
element, expressionPartText,
multiRm.add(
new DataRequestMonitor<Boolean>(getExecutor(), null) {
@Override
protected void handleCompleted() {
multiRm.requestMonitorDone(this);
}
}));
}
}
}
@Override
protected void handleErrorOrCancel() {
update.setStatus(getStatus());
update.done();
}
})
);
}
@ConfinedToDsfExecutor("#getSession#getExecutor")
protected abstract void testContextForExpression(Object element, final String expression, final DataRequestMonitor<Boolean> rm);
protected abstract void associateExpression(Object element, IExpression expression);
protected void getVMContextForExpressionFromChildNodes(final IChildrenUpdate update, Object parentElement, String childExpression, IExpression expression) {
IChildrenUpdate childUpdate = new ChildExpressionElementUpdate(
update, update.getElementPath().createChildPath(parentElement),
new DataRequestMonitor<List<Object>>(getExecutor(), null) {
@Override
protected void handleOK() {
update.setChild(getData().get(0), 0);
update.done();
}
@Override
protected void handleErrorOrCancel() {
update.setStatus(getStatus());
update.done();
}
});
for (int i = 0; i < getChildLayoutNodes().length; i++) {
if (getChildLayoutNodes()[i] instanceof IExpressionLayoutNode) {
IExpressionLayoutNode childNode = (IExpressionLayoutNode)getChildLayoutNodes()[i];
if (childNode.getExpressionLength(childExpression) > 0) {
// The child node will call update.done();
childNode.getElementForExpression(childUpdate, childExpression, expression);
return;
}
}
}
// If we didn't find a matching child node in the for loop above, return an error.
update.setStatus(new Status(IStatus.ERROR, DsfDebugUIPlugin.PLUGIN_ID, IDsfService.INTERNAL_ERROR, "Invalid expression", null)); //$NON-NLS-1$
update.done();
}
public int getDeltaFlagsForExpression(String expressionText, Object event) {
int exprLength = getExpressionLength(expressionText);
if (exprLength >= 0) {
if (exprLength == expressionText.length()) {
return getDeltaFlags(event);
} else {
int retVal = getDeltaFlagsForExpressionPart(event);
String childExpression = expressionText.substring(exprLength);
for (int i = 0; i < getChildLayoutNodes().length; i++) {
if (getChildLayoutNodes()[i] instanceof IExpressionLayoutNode) {
IExpressionLayoutNode exprNode = (IExpressionLayoutNode)getChildLayoutNodes()[i];
if (exprNode.getExpressionLength(childExpression) > 0) {
// The child node will call update.done();
retVal |= exprNode.getDeltaFlagsForExpression(childExpression, event);
}
}
}
return retVal;
}
}
return IModelDelta.NO_CHANGE;
}
protected abstract int getDeltaFlagsForExpressionPart(Object event);
public void buildDeltaForExpression(final IExpression expression, final int elementIdx, final String expressionText, final Object event, final VMDelta parentDelta, final TreePath path, final RequestMonitor rm)
{
// Find the expression part that belong to this node. If expression
// is not recognized, do nothing.
final int exprLength = getExpressionLength(expressionText);
if (exprLength < 0) {
rm.done();
return;
}
final String nodeExpressionText = exprLength > 0 ? expressionText.substring(0, exprLength) : expressionText;
getElementForExpressionPart(
new ElementsUpdate(new DataRequestMonitor<List<Object>>(getExecutor(), null), path),
nodeExpressionText,
new DataRequestMonitor<Object>(getExecutor(), null) {
@Override
protected void handleOK() {
if (exprLength == expressionText.length()) {
associateExpression(getData(), expression);
buildDeltaForExpressionElement(getData(), elementIdx, event, parentDelta, rm);
} else {
TreePath newPath = path.createChildPath(getData());
callChildExpressionNodesToBuildDelta(
expression, elementIdx, expressionText.substring(exprLength), event, parentDelta, newPath, rm);
}
}
@Override
protected void handleErrorOrCancel() {
// There is no matching element for given expression. That's OK, it just
// means that the expression is invalid.
rm.done();
}
});
}
protected void buildDeltaForExpressionElement(Object element, int elementIdx, Object event, VMDelta parentDelta, final RequestMonitor rm)
{
// Find the child nodes that have deltas for the given event.
final Map<IVMLayoutNode,Integer> childNodesWithDeltaFlags = getChildNodesWithDeltaFlags(event);
// If no child layout nodes have deltas we can stop here.
if (childNodesWithDeltaFlags.size() == 0) {
rm.done();
return;
}
callChildNodesToBuildDelta(
childNodesWithDeltaFlags, parentDelta.addNode(element, elementIdx, IModelDelta.NO_CHANGE), event, rm);
}
protected void callChildExpressionNodesToBuildDelta(IExpression expression, int elementIdx, String expressionRemainder, Object event, VMDelta parentDelta, TreePath path, final RequestMonitor rm)
{
final CountingRequestMonitor countingRm = new CountingRequestMonitor(getExecutor(), null) {
@Override
protected void handleCompleted() {
rm.done();
}
};
int childRmCount = 0;
for (int i = 0; i < getChildLayoutNodes().length; i++) {
if (getChildLayoutNodes()[i] instanceof IExpressionLayoutNode) {
IExpressionLayoutNode childNode = (IExpressionLayoutNode)getChildLayoutNodes()[i];
if (childNode.getExpressionLength(expressionRemainder) > 0 &&
childNode.getDeltaFlagsForExpression(expressionRemainder, event) != IModelDelta.NO_CHANGE)
{
childNode.buildDeltaForExpression(
expression, elementIdx, expressionRemainder, event, parentDelta, path, rm);
childRmCount++;
// The child node will call update.done();
}
}
}
if (childRmCount > 0) {
countingRm.setCount(childRmCount);
} else {
countingRm.done();
}
}
class ChildExpressionElementUpdate extends VMElementsUpdate {
private final TreePath fPath;
ChildExpressionElementUpdate(IChildrenUpdate clientUpdate, TreePath path, DataRequestMonitor<List<Object>> rm) {
super(clientUpdate, 0, 1, rm);
fPath = path;
}
@Override
public Object getElement() {
return fPath.getLastSegment();
}
@Override
public TreePath getElementPath() {
return fPath;
}
}
}

View file

@ -0,0 +1,75 @@
/*******************************************************************************
* Copyright (c) 2006 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.dd.dsf.debug.ui.viewmodel.expression;
import org.eclipse.dd.dsf.debug.ui.DsfDebugUIPlugin;
import org.eclipse.dd.dsf.debug.ui.viewmodel.IDebugVMConstants;
import org.eclipse.debug.internal.ui.viewers.model.provisional.IColumnPresentation;
import org.eclipse.debug.internal.ui.viewers.model.provisional.IPresentationContext;
import org.eclipse.jface.resource.ImageDescriptor;
/**
*
*/
@SuppressWarnings("restriction")
public class ExpressionColumnPresentation implements IColumnPresentation {
public static final String ID = DsfDebugUIPlugin.PLUGIN_ID + ".REGISTERS_COLUMN_PRESENTATION_ID"; //$NON-NLS-1$
public void init(IPresentationContext context) {
}
public void dispose() {
}
// @see org.eclipse.debug.internal.ui.viewers.provisional.IColumnPresentation#getAvailableColumns()
public String[] getAvailableColumns() {
return new String[] { IDebugVMConstants.COLUMN_ID__EXPRESSION, IDebugVMConstants.COLUMN_ID__NAME, IDebugVMConstants.COLUMN_ID__TYPE, IDebugVMConstants.COLUMN_ID__VALUE, IDebugVMConstants.COLUMN_ID__DESCRIPTION, };
}
// @see org.eclipse.debug.internal.ui.viewers.provisional.IColumnPresentation#getHeader(java.lang.String)
public String getHeader(String id) {
if (IDebugVMConstants.COLUMN_ID__EXPRESSION.equals(id)) {
return MessagesForExpressionVM.ExpressionColumnPresentation_expression;
} else if (IDebugVMConstants.COLUMN_ID__NAME.equals(id)) {
return MessagesForExpressionVM.ExpressionColumnPresentation_name;
} else if (IDebugVMConstants.COLUMN_ID__TYPE.equals(id)) {
return MessagesForExpressionVM.ExpressionColumnPresentation_type;
} else if (IDebugVMConstants.COLUMN_ID__VALUE.equals(id)) {
return MessagesForExpressionVM.ExpressionColumnPresentation_value;
} else if (IDebugVMConstants.COLUMN_ID__DESCRIPTION.equals(id)) {
return MessagesForExpressionVM.ExpressionColumnPresentation_description;
}
return null;
}
// @see org.eclipse.debug.internal.ui.viewers.provisional.IColumnPresentation#getId()
public String getId() {
return ID;
}
public ImageDescriptor getImageDescriptor(String id) {
return null;
}
// @see org.eclipse.debug.internal.ui.viewers.provisional.IColumnPresentation#getInitialColumns()
public String[] getInitialColumns() {
return new String[] { IDebugVMConstants.COLUMN_ID__EXPRESSION, IDebugVMConstants.COLUMN_ID__VALUE };
}
// @see org.eclipse.debug.internal.ui.viewers.provisional.IColumnPresentation#isOptional()
public boolean isOptional() {
return true;
}
}

View file

@ -0,0 +1,293 @@
/*******************************************************************************
* Copyright (c) 2006 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.dd.dsf.debug.ui.viewmodel.expression;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.eclipse.dd.dsf.concurrent.CountingRequestMonitor;
import org.eclipse.dd.dsf.concurrent.DataRequestMonitor;
import org.eclipse.dd.dsf.concurrent.RequestMonitor;
import org.eclipse.dd.dsf.debug.ui.viewmodel.IDebugVMConstants;
import org.eclipse.dd.dsf.debug.ui.viewmodel.expression.ExpressionVMProvider.ExpressionsChangedEvent;
import org.eclipse.dd.dsf.ui.viewmodel.AbstractVMLayoutNode;
import org.eclipse.dd.dsf.ui.viewmodel.AbstractVMProvider;
import org.eclipse.dd.dsf.ui.viewmodel.IVMLayoutNode;
import org.eclipse.dd.dsf.ui.viewmodel.VMDelta;
import org.eclipse.dd.dsf.ui.viewmodel.VMElementsUpdate;
import org.eclipse.debug.core.DebugPlugin;
import org.eclipse.debug.core.IExpressionManager;
import org.eclipse.debug.core.model.IExpression;
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.IElementEditor;
import org.eclipse.debug.internal.ui.viewers.model.provisional.IElementLabelProvider;
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.debug.ui.DebugUITools;
import org.eclipse.debug.ui.IDebugUIConstants;
import org.eclipse.jface.viewers.CellEditor;
import org.eclipse.jface.viewers.ICellModifier;
import org.eclipse.jface.viewers.TextCellEditor;
import org.eclipse.swt.widgets.Composite;
@SuppressWarnings("restriction")
public class ExpressionManagerLayoutNode extends AbstractVMLayoutNode
implements IElementLabelProvider, IElementEditor
{
private class InvalidExpressionVMC extends AbstractVMContext {
final IExpression fExpression;
public InvalidExpressionVMC(IExpression expression) {
super(getVMProvider().getVMAdapter(), ExpressionManagerLayoutNode.this);
fExpression = expression;
}
@Override
@SuppressWarnings("unchecked")
public Object getAdapter(Class adapter) {
if (adapter.isAssignableFrom(fExpression.getClass())) {
return fExpression;
} else {
return super.getAdapter(adapter);
}
}
@Override
public boolean equals(Object obj) {
return obj instanceof InvalidExpressionVMC && ((InvalidExpressionVMC)obj).fExpression.equals(fExpression);
}
@Override
public int hashCode() {
return fExpression.hashCode();
}
}
private IExpressionLayoutNode[] fExpressionNodes = new IExpressionLayoutNode[0];
private IExpressionManager fManager = DebugPlugin.getDefault().getExpressionManager();
private WatchExpressionCellModifier fWatchExpressionCellModifier = new WatchExpressionCellModifier();
public ExpressionManagerLayoutNode(AbstractVMProvider provider) {
super(provider);
}
public void updateHasElements(IHasChildrenUpdate[] updates) {
for (int i = 0; i < updates.length; i++) {
updates[i].setHasChilren(fManager.getExpressions().length != 0);
updates[i].done();
}
}
public void updateElementCount(IChildrenCountUpdate update) {
update.setChildCount(fManager.getExpressions().length);
update.done();
}
public void updateElements(final IChildrenUpdate update) {
final IExpression[] expressions = fManager.getExpressions();
final CountingRequestMonitor multiRm = new CountingRequestMonitor(getExecutor(), null) {
@Override
protected void handleCompleted() {
update.done();
}
};
int expressionRmCount = 0;
for (int i = update.getOffset(); i < update.getOffset() + update.getLength() && i < expressions.length; i++) {
// Check the array boundries as the expression manager could change asynchronously.
// The expression manager change should lead to a refresh in the view.
if (i > expressions.length) {
continue;
}
final String expressionText = expressions[i].getExpressionText();
final int expressionIdx = i;
final IExpression expression = expressions[i];
IExpressionLayoutNode expressionNode = findNodeForExpression(expressionText);
if (expressionNode == null) {
update.setChild(new InvalidExpressionVMC(expression), i);
} else {
expressionRmCount++;
VMElementsUpdate expressionElementUpdate = new VMElementsUpdate(
update, 0, 1,
new DataRequestMonitor<List<Object>>(getExecutor(), multiRm) {
@Override
protected void handleOK() {
update.setChild(getData().get(0), expressionIdx);
multiRm.done();
}
@Override
protected void handleError() {
update.setChild(new InvalidExpressionVMC(expression), expressionIdx);
multiRm.done();
}
});
expressionNode.getElementForExpression(expressionElementUpdate, expressionText, expression);
}
}
if (expressionRmCount > 0) {
multiRm.setCount(expressionRmCount);
} else {
multiRm.done();
}
}
public void update(ILabelUpdate[] updates) {
for (ILabelUpdate update : updates) {
if (update.getElement() instanceof InvalidExpressionVMC) {
updateInvalidExpressionVMCLabel(update, (InvalidExpressionVMC) update.getElement());
} else {
update.done();
}
}
}
private void updateInvalidExpressionVMCLabel(ILabelUpdate update, InvalidExpressionVMC vmc) {
String[] columnIds = update.getColumnIds() != null ?
update.getColumnIds() : new String[] { IDebugVMConstants.COLUMN_ID__NAME };
for (int i = 0; i < columnIds.length; i++) {
if (IDebugVMConstants.COLUMN_ID__EXPRESSION.equals(columnIds[i])) {
update.setLabel(vmc.fExpression.getExpressionText(), i);
update.setImageDescriptor(DebugUITools.getImageDescriptor( IDebugUIConstants.IMG_OBJS_EXPRESSION ), i);
} else if (IDebugVMConstants.COLUMN_ID__NAME.equals(columnIds[i])) {
update.setLabel(vmc.fExpression.getExpressionText(), i);
update.setImageDescriptor(DebugUITools.getImageDescriptor( IDebugUIConstants.IMG_OBJS_EXPRESSION ), i);
} else if (IDebugVMConstants.COLUMN_ID__VALUE.equals(columnIds[i])) {
update.setLabel(MessagesForExpressionVM.ExpressionManagerLayoutNode__invalidExpression_valueColumn_label, i);
} else {
update.setLabel("", i); //$NON-NLS-1$
}
}
update.done();
}
private IExpressionLayoutNode findNodeForExpression(String expressionText) {
for (IExpressionLayoutNode node : fExpressionNodes) {
if (node.getExpressionLength(expressionText) > 0) {
return node;
}
}
return null;
}
@Override
public void setChildNodes(IVMLayoutNode[] childNodes) {
throw new UnsupportedOperationException("This node does not support children."); //$NON-NLS-1$
}
public void setExpressionLayoutNodes(IExpressionLayoutNode[] nodes) {
fExpressionNodes = nodes;
}
@Override
public void dispose() {
for (IExpressionLayoutNode exprNode : fExpressionNodes) {
exprNode.dispose();
}
super.dispose();
}
/**
* If any of the children nodes have delta flags, that means that this
* node has to generate a delta as well.
*/
@Override
public int getDeltaFlags(Object event) {
int retVal = 0;
// Add a flag if the list of expressions has changed.
if (event instanceof ExpressionsChangedEvent) {
retVal |= IModelDelta.CONTENT;
}
for (IExpressionLayoutNode node : fExpressionNodes) {
retVal |= node.getDeltaFlags(event);
}
return retVal;
}
@Override
public void buildDelta(final Object event, final VMDelta parentDelta, final int nodeOffset, final RequestMonitor requestMonitor) {
// Add a flag if the list of expressions has changed.
if (event instanceof ExpressionsChangedEvent) {
parentDelta.addFlags(IModelDelta.CONTENT);
}
CountingRequestMonitor multiRm = new CountingRequestMonitor(getExecutor(), requestMonitor);
int buildDeltaForExpressionCallCount = 0;
IExpression[] expressions = fManager.getExpressions();
for (int i = 0; i < expressions.length; i++ ) {
String expressionText = expressions[i].getExpressionText();
IExpressionLayoutNode node = findNodeForExpression(expressionText);
if (node == null) continue;
int flags = node.getDeltaFlagsForExpression(expressionText, event);
// If the given node has no delta flags, skip it.
if (flags == IModelDelta.NO_CHANGE) continue;
node.buildDeltaForExpression(expressions[i], i + nodeOffset, expressionText, event, parentDelta,
getTreePathFromDelta(parentDelta),
new RequestMonitor(getExecutor(), multiRm));
buildDeltaForExpressionCallCount++;
}
if (buildDeltaForExpressionCallCount != 0) {
multiRm.setCount(buildDeltaForExpressionCallCount);
} else {
requestMonitor.done();
}
}
/**
* Convenience method that returns the child layout nodes which return
* <code>true</code> to the <code>hasDeltaFlags()</code> test for the given
* event.
*/
protected Map<IExpressionLayoutNode, Integer> getExpressionsWithDeltaFlags(String expressionText, Object e) {
Map<IExpressionLayoutNode, Integer> nodes = new HashMap<IExpressionLayoutNode, Integer>();
for (final IExpressionLayoutNode node : fExpressionNodes) {
int delta = node.getDeltaFlagsForExpression(expressionText, e);
if (delta != IModelDelta.NO_CHANGE) {
nodes.put(node, delta);
}
}
return nodes;
}
public CellEditor getCellEditor(IPresentationContext context, String columnId, Object element, Composite parent) {
if (IDebugVMConstants.COLUMN_ID__EXPRESSION.equals(columnId)) {
return new TextCellEditor(parent);
}
return null;
}
public ICellModifier getCellModifier(IPresentationContext context, Object element) {
return fWatchExpressionCellModifier;
}
}

View file

@ -0,0 +1,123 @@
/*******************************************************************************
* Copyright (c) 2006 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.dd.dsf.debug.ui.viewmodel.expression;
import org.eclipse.dd.dsf.debug.ui.viewmodel.DebugViewSelectionRootLayoutNode;
import org.eclipse.dd.dsf.debug.ui.viewmodel.register.RegisterGroupLayoutNode;
import org.eclipse.dd.dsf.debug.ui.viewmodel.register.RegisterLayoutNode;
import org.eclipse.dd.dsf.debug.ui.viewmodel.register.SyncRegisterDataAccess;
import org.eclipse.dd.dsf.service.DsfSession;
import org.eclipse.dd.dsf.ui.viewmodel.AbstractVMAdapter;
import org.eclipse.dd.dsf.ui.viewmodel.IVMContext;
import org.eclipse.dd.dsf.ui.viewmodel.IVMLayoutNode;
import org.eclipse.dd.dsf.ui.viewmodel.IVMRootLayoutNode;
import org.eclipse.dd.dsf.ui.viewmodel.dm.AbstractDMVMProvider;
import org.eclipse.debug.core.DebugPlugin;
import org.eclipse.debug.core.IExpressionsListener;
import org.eclipse.debug.core.model.IExpression;
import org.eclipse.debug.internal.ui.viewers.model.provisional.IColumnPresentation;
import org.eclipse.debug.internal.ui.viewers.model.provisional.IPresentationContext;
/**
*
*/
@SuppressWarnings("restriction")
public class ExpressionVMProvider extends AbstractDMVMProvider
implements IExpressionsListener
{
public static class ExpressionsChangedEvent {
enum Type {ADDED, CHANGED, REMOVED}
public final Type fType;
public final IExpression[] fExpressions;
public ExpressionsChangedEvent(Type type, IExpression[] expressions) {
fType = type;
fExpressions = expressions;
}
}
public ExpressionVMProvider(AbstractVMAdapter adapter, IPresentationContext context, DsfSession session) {
super(adapter, context, session);
// The VM provider has to handle all events that result in model deltas.
// Add the provider as listener to expression changes events.
DebugPlugin.getDefault().getExpressionManager().addExpressionListener(this);
configureLayout();
}
protected void configureLayout() {
SyncRegisterDataAccess syncDataAccess = new SyncRegisterDataAccess();
// Configure the layout nodes
IVMRootLayoutNode debugViewSelectionNode = new DebugViewSelectionRootLayoutNode(this);
ExpressionManagerLayoutNode expressionManagerNode = new ExpressionManagerLayoutNode(this);
debugViewSelectionNode.setChildNodes(new IVMLayoutNode[] {expressionManagerNode});
IExpressionLayoutNode registerGroupNode = new RegisterGroupLayoutNode(this, getSession(), syncDataAccess);
expressionManagerNode.setExpressionLayoutNodes(new IExpressionLayoutNode[] { registerGroupNode });
IVMLayoutNode registerNode = new RegisterLayoutNode(this, getSession(), syncDataAccess);
registerGroupNode.setChildNodes(new IVMLayoutNode[] { registerNode });
setRootLayoutNode(debugViewSelectionNode);
}
@Override
public void dispose() {
DebugPlugin.getDefault().getExpressionManager().removeExpressionListener(this);
super.dispose();
}
@Override
public IColumnPresentation createColumnPresentation(IPresentationContext context, Object element) {
return new ExpressionColumnPresentation();
}
@Override
public String getColumnPresentationId(IPresentationContext context, Object element) {
return ExpressionColumnPresentation.ID;
}
/**
* Override this operation to avoid the standard test of isOurLayoutNode(),
* which does not take into account {@link ExpressionManagerLayoutNode.setExpressionLayoutNodes}
* nodes.
*/
@Override
protected IVMLayoutNode getLayoutNodeForElement(Object element) {
/*
* First check to see if the parent object is the root object of the
* hierarchy. If that's the case, then retrieve the correcponding
* root VMC from the root node, and pass this root vmc to the root's
* child layout nodes.
*/
IVMRootLayoutNode rootLayoutNode = getRootLayoutNode();
if (rootLayoutNode == null) {
return null;
}
else if (element.equals(rootLayoutNode.getRootObject())) {
return rootLayoutNode;
}
else if (element instanceof IVMContext){
return ((IVMContext)element).getLayoutNode();
}
return null;
}
public void expressionsAdded(IExpression[] expressions) {
handleEvent(new ExpressionsChangedEvent(ExpressionsChangedEvent.Type.ADDED, expressions));
}
public void expressionsChanged(IExpression[] expressions) {
handleEvent(new ExpressionsChangedEvent(ExpressionsChangedEvent.Type.CHANGED, expressions));
}
public void expressionsRemoved(IExpression[] expressions) {
handleEvent(new ExpressionsChangedEvent(ExpressionsChangedEvent.Type.REMOVED, expressions));
}
}

View file

@ -0,0 +1,31 @@
/*******************************************************************************
* Copyright (c) 2007 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.dd.dsf.debug.ui.viewmodel.expression;
import org.eclipse.dd.dsf.concurrent.RequestMonitor;
import org.eclipse.dd.dsf.ui.viewmodel.IVMLayoutNode;
import org.eclipse.dd.dsf.ui.viewmodel.VMDelta;
import org.eclipse.debug.core.model.IExpression;
import org.eclipse.debug.internal.ui.viewers.model.provisional.IChildrenUpdate;
import org.eclipse.jface.viewers.TreePath;
/**
*
*/
@SuppressWarnings("restriction")
public interface IExpressionLayoutNode extends IVMLayoutNode {
int getExpressionLength(String expression);
void getElementForExpression(IChildrenUpdate update, String expressionText, IExpression expression);
int getDeltaFlagsForExpression(String expressionText, Object event);
void buildDeltaForExpression(IExpression expression, int elementIdx, String expressionText, Object event,
VMDelta parentDelta, TreePath path, RequestMonitor rm);
}

View file

@ -0,0 +1,19 @@
/*******************************************************************************
* Copyright (c) 2007 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.dd.dsf.debug.ui.viewmodel.expression;
import org.eclipse.dd.dsf.ui.viewmodel.IVMContext;
/**
*
*/
public interface IExpressionVMContext extends IVMContext {
}

View file

@ -0,0 +1,24 @@
package org.eclipse.dd.dsf.debug.ui.viewmodel.expression;
import org.eclipse.osgi.util.NLS;
public class MessagesForExpressionVM extends NLS {
private static final String BUNDLE_NAME = "org.eclipse.dd.dsf.debug.ui.viewmodel.expression.messages"; //$NON-NLS-1$
public static String ExpressionColumnPresentation_expression;
public static String ExpressionColumnPresentation_name;
public static String ExpressionColumnPresentation_type;
public static String ExpressionColumnPresentation_value;
public static String ExpressionColumnPresentation_description;
public static String ExpressionManagerLayoutNode__invalidExpression_nameColumn_label;
public static String ExpressionManagerLayoutNode__invalidExpression_valueColumn_label;
static {
// initialize resource bundle
NLS.initializeMessages(BUNDLE_NAME, MessagesForExpressionVM.class);
}
private MessagesForExpressionVM() {
}
}

View file

@ -0,0 +1,66 @@
/*******************************************************************************
* Copyright (c) 2006 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.dd.dsf.debug.ui.viewmodel.expression;
import org.eclipse.core.runtime.IAdaptable;
import org.eclipse.dd.dsf.concurrent.ThreadSafeAndProhibitedFromDsfExecutor;
import org.eclipse.dd.dsf.debug.ui.viewmodel.IDebugVMConstants;
import org.eclipse.debug.core.model.IWatchExpression;
import org.eclipse.jface.viewers.ICellModifier;
/**
*
*/
@SuppressWarnings("restriction")
@ThreadSafeAndProhibitedFromDsfExecutor("")
public class WatchExpressionCellModifier implements ICellModifier {
/**
* Constructor for the modifier requires a valid DSF session in order to
* initialize the service tracker.
* @param session DSF session this modifier will use.
*/
public WatchExpressionCellModifier() {
}
public boolean canModify(Object element, String property) {
return IDebugVMConstants.COLUMN_ID__EXPRESSION.equals(property) && getWatchExpression(element) != null;
}
public Object getValue(Object element, String property) {
if (!IDebugVMConstants.COLUMN_ID__EXPRESSION.equals(property)) return ""; //$NON-NLS-1$
IWatchExpression expression = getWatchExpression(element);
if (expression != null) {
return expression.getExpressionText();
}
return ""; //$NON-NLS-1$
}
public void modify(Object element, String property, Object value) {
if (!IDebugVMConstants.COLUMN_ID__EXPRESSION.equals(property)) return;
IWatchExpression expression = getWatchExpression(element);
if (expression != null && value instanceof String) {
expression.setExpressionText((String)value);
}
}
private IWatchExpression getWatchExpression(Object element) {
if (element instanceof IAdaptable) {
return (IWatchExpression)((IAdaptable)element).getAdapter(IWatchExpression.class);
}
return null;
}
}

View file

@ -0,0 +1,33 @@
/*******************************************************************************
* Copyright (c) 2007 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.dd.dsf.debug.ui.viewmodel.expression;
import org.eclipse.debug.core.DebugException;
import org.eclipse.debug.core.model.IDebugElement;
import org.eclipse.debug.core.model.IValue;
import org.eclipse.debug.core.model.IWatchExpressionDelegate;
import org.eclipse.debug.core.model.IWatchExpressionListener;
import org.eclipse.debug.core.model.IWatchExpressionResult;
/**
*
*/
public class WatchExpressionDelegate implements IWatchExpressionDelegate {
public void evaluateExpression(final String expression, IDebugElement context, IWatchExpressionListener listener) {
listener.watchEvaluationFinished(new IWatchExpressionResult() {
public String[] getErrorMessages() { return new String[0]; }
public DebugException getException() { return null; }
public String getExpressionText() { return expression; }
public IValue getValue() { return null; }
public boolean hasErrors() { return false; }
});
}
}

View file

@ -0,0 +1,7 @@
ExpressionColumnPresentation_expression=Expression
ExpressionColumnPresentation_name=Name
ExpressionColumnPresentation_type=Type
ExpressionColumnPresentation_value=Value
ExpressionColumnPresentation_description=Description
ExpressionManagerLayoutNode__invalidExpression_nameColumn_label=Invalid expression
ExpressionManagerLayoutNode__invalidExpression_valueColumn_label=Invalid expression

View file

@ -12,8 +12,8 @@ package org.eclipse.dd.dsf.debug.ui.viewmodel.launch;
import java.util.List;
import org.eclipse.dd.dsf.concurrent.RequestMonitor;
import org.eclipse.dd.dsf.concurrent.DataRequestMonitor;
import org.eclipse.dd.dsf.concurrent.RequestMonitor;
import org.eclipse.dd.dsf.datamodel.IDMContext;
import org.eclipse.dd.dsf.datamodel.IDMEvent;
import org.eclipse.dd.dsf.debug.service.IRunControl;

View file

@ -66,7 +66,7 @@ public class StandardLaunchRootLayoutNode extends AbstractVMRootLayoutNode
return IModelDelta.NO_CHANGE;
}
else if (de.getSource() instanceof IDebugElement &&
!((IDebugElement)de.getSource()).getLaunch().equals(fLaunch) )
!fLaunch.equals(((IDebugElement)de.getSource()).getLaunch()))
{
return IModelDelta.NO_CHANGE;
}

View file

@ -11,6 +11,7 @@
package org.eclipse.dd.dsf.debug.ui.viewmodel.register;
import org.eclipse.dd.dsf.debug.ui.DsfDebugUIPlugin;
import org.eclipse.dd.dsf.debug.ui.viewmodel.IDebugVMConstants;
import org.eclipse.debug.internal.ui.viewers.model.provisional.IColumnPresentation;
import org.eclipse.debug.internal.ui.viewers.model.provisional.IPresentationContext;
import org.eclipse.jface.resource.ImageDescriptor;
@ -22,28 +23,25 @@ import org.eclipse.jface.resource.ImageDescriptor;
public class RegisterColumnPresentation implements IColumnPresentation {
public static final String ID = DsfDebugUIPlugin.PLUGIN_ID + ".REGISTERS_COLUMN_PRESENTATION_ID"; //$NON-NLS-1$
public static final String COL_NAME = ID + ".COL_NAME"; //$NON-NLS-1$
public static final String COL_VALUE = ID + ".COL_VALUE"; //$NON-NLS-1$
public static final String COL_DESCRIPTION = ID + ".COL_DESCRIPTION"; //$NON-NLS-1$
// @see org.eclipse.debug.internal.ui.viewers.provisional.IColumnPresentation#init(org.eclipse.debug.internal.ui.viewers.provisional.IPresentationContext)
public void init(IPresentationContext context) {}
// @see org.eclipse.debug.internal.ui.viewers.provisional.IColumnPresentation#dispose()
public void dispose() {}
public void init(IPresentationContext context) {
}
public void dispose() {
}
// @see org.eclipse.debug.internal.ui.viewers.provisional.IColumnPresentation#getAvailableColumns()
public String[] getAvailableColumns() {
return new String[] { COL_NAME, COL_VALUE, COL_DESCRIPTION };
return new String[] { IDebugVMConstants.COLUMN_ID__NAME, IDebugVMConstants.COLUMN_ID__VALUE, IDebugVMConstants.COLUMN_ID__DESCRIPTION, };
}
// @see org.eclipse.debug.internal.ui.viewers.provisional.IColumnPresentation#getHeader(java.lang.String)
public String getHeader(String id) {
if (COL_NAME.equals(id)) {
if (IDebugVMConstants.COLUMN_ID__NAME.equals(id)) {
return MessagesForRegisterVM.RegisterColumnPresentation_name;
} else if (COL_VALUE.equals(id)) {
} else if (IDebugVMConstants.COLUMN_ID__VALUE.equals(id)) {
return MessagesForRegisterVM.RegisterColumnPresentation_value;
} else if (COL_DESCRIPTION.equals(id)) {
} else if (IDebugVMConstants.COLUMN_ID__DESCRIPTION.equals(id)) {
return MessagesForRegisterVM.RegisterColumnPresentation_description;
}
return null;
@ -53,17 +51,18 @@ public class RegisterColumnPresentation implements IColumnPresentation {
public String getId() {
return ID;
}
// @see org.eclipse.debug.internal.ui.viewers.provisional.IColumnPresentation#getImageDescriptor(java.lang.String)
public ImageDescriptor getImageDescriptor(String id) {
return null;
}
}
// @see org.eclipse.debug.internal.ui.viewers.provisional.IColumnPresentation#getInitialColumns()
public String[] getInitialColumns() {
return new String[] { COL_NAME, COL_VALUE };
return new String[] { IDebugVMConstants.COLUMN_ID__NAME, IDebugVMConstants.COLUMN_ID__VALUE, IDebugVMConstants.COLUMN_ID__DESCRIPTION };
}
// @see org.eclipse.debug.internal.ui.viewers.provisional.IColumnPresentation#isOptional()
public boolean isOptional() {
return true;

View file

@ -10,30 +10,144 @@
*******************************************************************************/
package org.eclipse.dd.dsf.debug.ui.viewmodel.register;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.dd.dsf.concurrent.DataRequestMonitor;
import org.eclipse.dd.dsf.concurrent.RequestMonitor;
import org.eclipse.dd.dsf.datamodel.DMContexts;
import org.eclipse.dd.dsf.datamodel.IDMContext;
import org.eclipse.dd.dsf.datamodel.IDMEvent;
import org.eclipse.dd.dsf.datamodel.IDMService;
import org.eclipse.dd.dsf.debug.service.IRegisters;
import org.eclipse.dd.dsf.debug.service.IRunControl;
import org.eclipse.dd.dsf.debug.service.IRegisters.IRegisterGroupDMContext;
import org.eclipse.dd.dsf.debug.service.IRegisters.IRegisterGroupDMData;
import org.eclipse.dd.dsf.debug.service.IRunControl.IExecutionDMContext;
import org.eclipse.dd.dsf.debug.ui.DsfDebugUIPlugin;
import org.eclipse.dd.dsf.debug.ui.viewmodel.IDebugVMConstants;
import org.eclipse.dd.dsf.debug.ui.viewmodel.expression.AbstractExpressionLayoutNode;
import org.eclipse.dd.dsf.debug.ui.viewmodel.expression.WatchExpressionCellModifier;
import org.eclipse.dd.dsf.service.DsfSession;
import org.eclipse.dd.dsf.service.IDsfService;
import org.eclipse.dd.dsf.ui.viewmodel.AbstractVMProvider;
import org.eclipse.dd.dsf.ui.viewmodel.IVMContext;
import org.eclipse.dd.dsf.ui.viewmodel.VMDelta;
import org.eclipse.dd.dsf.ui.viewmodel.dm.AbstractDMVMLayoutNode;
import org.eclipse.debug.core.DebugException;
import org.eclipse.debug.core.ILaunch;
import org.eclipse.debug.core.model.IDebugTarget;
import org.eclipse.debug.core.model.IExpression;
import org.eclipse.debug.core.model.IValue;
import org.eclipse.debug.core.model.IVariable;
import org.eclipse.debug.internal.ui.viewers.model.provisional.IChildrenUpdate;
import org.eclipse.debug.internal.ui.viewers.model.provisional.IElementEditor;
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.debug.ui.actions.IWatchExpressionFactoryAdapterExtension;
import org.eclipse.jface.viewers.CellEditor;
import org.eclipse.jface.viewers.ICellModifier;
import org.eclipse.jface.viewers.TextCellEditor;
import org.eclipse.jface.viewers.TreePath;
import org.eclipse.swt.widgets.Composite;
@SuppressWarnings("restriction")
public class RegisterGroupLayoutNode extends AbstractDMVMLayoutNode<IRegisterGroupDMData> {
public class RegisterGroupLayoutNode extends AbstractExpressionLayoutNode<IRegisterGroupDMData>
implements IElementEditor
{
public RegisterGroupLayoutNode(AbstractVMProvider provider, DsfSession session) {
super(provider, session, IRegisters.IRegisterGroupDMContext.class);
protected class RegisterGroupVMC extends DMVMContext
implements IVariable
{
private IExpression fExpression;
public RegisterGroupVMC(IDMContext<?> dmc) {
super(dmc);
}
public void setExpression(IExpression expression) {
fExpression = expression;
}
@Override
@SuppressWarnings("unchecked")
public Object getAdapter(Class adapter) {
if (fExpression != null && adapter.isAssignableFrom(fExpression.getClass())) {
return fExpression;
} else if (adapter.isAssignableFrom(IWatchExpressionFactoryAdapterExtension.class)) {
return fRegisterGroupExpressionFactory;
} else {
return super.getAdapter(adapter);
}
}
@Override
public boolean equals(Object other) {
if (other instanceof RegisterGroupVMC && super.equals(other)) {
RegisterGroupVMC otherGroup = (RegisterGroupVMC)other;
return (otherGroup.fExpression == null && fExpression == null) ||
(otherGroup.fExpression != null && otherGroup.fExpression.equals(fExpression));
}
return false;
}
@Override
public int hashCode() {
return super.hashCode() + (fExpression != null ? fExpression.hashCode() : 0);
}
public String getName() throws DebugException { return toString(); }
public String getReferenceTypeName() throws DebugException { return ""; } //$NON-NLS-1$
public IValue getValue() throws DebugException { return null; }
public boolean hasValueChanged() throws DebugException { return false; }
public void setValue(IValue value) throws DebugException {}
public void setValue(String expression) throws DebugException {}
public boolean supportsValueModification() { return false; }
public boolean verifyValue(IValue value) throws DebugException { return false; }
public boolean verifyValue(String expression) throws DebugException { return false; }
public IDebugTarget getDebugTarget() { return null;}
public ILaunch getLaunch() { return null; }
public String getModelIdentifier() { return DsfDebugUIPlugin.PLUGIN_ID; }
}
protected class RegisterGroupExpressionFactory implements IWatchExpressionFactoryAdapterExtension {
public boolean canCreateWatchExpression(IVariable variable) {
return variable instanceof RegisterGroupVMC;
}
public String createWatchExpression(IVariable variable) throws CoreException {
RegisterGroupVMC registerVmc = ((RegisterGroupVMC)variable);
StringBuffer exprBuf = new StringBuffer();
IRegisterGroupDMContext groupDmc =
DMContexts.getAncestorOfType(registerVmc.getDMC(), IRegisterGroupDMContext.class);
IRegisterGroupDMData groupData = fSyncRegisterDataAccess.readRegisterGroup(groupDmc);
if (groupData != null) {
exprBuf.append("$$\""); //$NON-NLS-1$
exprBuf.append(groupData.getName());
exprBuf.append('"');
return exprBuf.toString();
}
return null;
}
}
final private SyncRegisterDataAccess fSyncRegisterDataAccess;
final protected RegisterGroupExpressionFactory fRegisterGroupExpressionFactory = new RegisterGroupExpressionFactory();
private WatchExpressionCellModifier fWatchExpressionCellModifier = new WatchExpressionCellModifier();
public RegisterGroupLayoutNode(AbstractVMProvider provider, DsfSession session, SyncRegisterDataAccess syncDataAccess) {
super(provider, session, IRegisters.IRegisterGroupDMContext.class);
fSyncRegisterDataAccess = syncDataAccess;
}
protected SyncRegisterDataAccess getSyncRegisterDataAccess() {
return fSyncRegisterDataAccess;
}
@Override
protected void updateElementsInSessionThread(final IChildrenUpdate update) {
if (!checkService(IRegisters.class, null, update)) return;
@ -59,16 +173,30 @@ public class RegisterGroupLayoutNode extends AbstractDMVMLayoutNode<IRegisterGro
}
@Override
protected IVMContext createVMContext(IDMContext<IRegisterGroupDMData> dmc) {
return new RegisterGroupVMC(dmc);
}
@Override
protected void fillColumnLabel(IDMContext<IRegisterGroupDMData> dmContext, IRegisterGroupDMData dmData,
String columnId, int idx, ILabelUpdate update)
{
if (RegisterColumnPresentation.COL_NAME.equals(columnId)) {
if (IDebugVMConstants.COLUMN_ID__NAME.equals(columnId)) {
update.setLabel(dmData.getName(), idx);
} else if (RegisterColumnPresentation.COL_VALUE.equals(columnId)) {
} else if (IDebugVMConstants.COLUMN_ID__VALUE.equals(columnId)) {
update.setLabel("", idx); //$NON-NLS-1$
} else if (RegisterColumnPresentation.COL_DESCRIPTION.equals(columnId)) {
} else if (IDebugVMConstants.COLUMN_ID__DESCRIPTION.equals(columnId)) {
update.setLabel(dmData.getDescription(), idx);
} else if (IDebugVMConstants.COLUMN_ID__EXPRESSION.equals(columnId)) {
IVMContext vmc = (IVMContext)update.getElement();
IExpression expression = (IExpression)vmc.getAdapter(IExpression.class);
if (expression != null) {
update.setLabel(expression.getExpressionText(), idx);
} else {
update.setLabel(dmData.getName(), idx);
}
}
}
@ -89,9 +217,100 @@ public class RegisterGroupLayoutNode extends AbstractDMVMLayoutNode<IRegisterGro
parent.addFlags(IModelDelta.CONTENT);
}
if (e instanceof IRegisters.IRegistersChangedDMEvent) {
parent.addNode( new DMVMContext(((IRegisters.IRegistersChangedDMEvent)e).getDMContext()), IModelDelta.STATE );
parent.addNode( createVMContext(((IRegisters.IRegistersChangedDMEvent)e).getDMContext()), IModelDelta.STATE );
}
super.buildDeltaForDMEvent(e, parent, nodeOffset, rm);
}
public int getExpressionLength(String expression) {
if (expression.startsWith("$$\"")) { //$NON-NLS-1$
int secondQuoteIdx = expression.indexOf('"', "$$\"".length()); //$NON-NLS-1$
if (secondQuoteIdx > 0) {
return secondQuoteIdx + 1;
}
}
return -1;
}
@Override
protected int getDeltaFlagsForExpressionPart(Object event) {
if (event instanceof IRunControl.ISuspendedDMEvent) {
return IModelDelta.CONTENT;
}
return IModelDelta.NO_CHANGE;
}
@Override
public void buildDeltaForExpression(final IExpression expression, final int elementIdx, final String expressionText, final Object event, final VMDelta parentDelta, final TreePath path, final RequestMonitor rm)
{
if (event instanceof IRunControl.ISuspendedDMEvent) {
// Mark the partent delta indicating that elements were added and/or removed.
parentDelta.addFlags(IModelDelta.CONTENT);
}
super.buildDeltaForExpression(expression, elementIdx, expressionText, event, parentDelta, path, rm);
}
@Override
protected void buildDeltaForExpressionElement(Object element, int elementIdx, Object event, VMDelta parentDelta, final RequestMonitor rm)
{
if (event instanceof IRegisters.IRegistersChangedDMEvent) {
parentDelta.addNode(element, IModelDelta.STATE);
}
super.buildDeltaForExpressionElement(element, elementIdx, event, parentDelta, rm);
}
@Override
protected void testContextForExpression(Object element, final String expression, final DataRequestMonitor<Boolean> rm) {
if (!(element instanceof AbstractDMVMLayoutNode.DMVMContext)) {
rm.setStatus(new Status(IStatus.ERROR, DsfDebugUIPlugin.PLUGIN_ID, IDsfService.INVALID_HANDLE, "Invalid context", null)); //$NON-NLS-1$
rm.done();
return;
}
final IRegisterGroupDMContext dmc = DMContexts.getAncestorOfType(((DMVMContext)element).getDMC(), IRegisterGroupDMContext.class);
if (dmc == null) {
rm.setStatus(new Status(IStatus.ERROR, DsfDebugUIPlugin.PLUGIN_ID, IDsfService.INVALID_HANDLE, "Invalid context", null)); //$NON-NLS-1$
rm.done();
return;
}
((IDMService)getServicesTracker().getService(null, dmc.getServiceFilter())).getModelData(
dmc,
new DataRequestMonitor<IRegisterGroupDMData>(getSession().getExecutor(), rm) {
@Override
protected void handleOK() {
int startIdx = "$$\"".length(); //$NON-NLS-1$
int endIdx = expression.indexOf('"', startIdx);
String groupName = expression.substring(startIdx, endIdx);
if (groupName.equals(getData().getName())) {
rm.setData(Boolean.TRUE);
} else {
rm.setData(Boolean.FALSE);
}
rm.done();
}
});
}
@Override
protected void associateExpression(Object element, IExpression expression) {
if (element instanceof RegisterGroupVMC) {
((RegisterGroupVMC)element).setExpression(expression);
}
}
public CellEditor getCellEditor(IPresentationContext context, String columnId, Object element, Composite parent) {
if (IDebugVMConstants.COLUMN_ID__EXPRESSION.equals(columnId)) {
return new TextCellEditor(parent);
}
return null;
}
public ICellModifier getCellModifier(IPresentationContext context, Object element) {
return fWatchExpressionCellModifier;
}
}

View file

@ -10,8 +10,13 @@
*******************************************************************************/
package org.eclipse.dd.dsf.debug.ui.viewmodel.register;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.dd.dsf.concurrent.DataRequestMonitor;
import org.eclipse.dd.dsf.concurrent.RequestMonitor;
import org.eclipse.dd.dsf.datamodel.DMContexts;
import org.eclipse.dd.dsf.datamodel.IDMContext;
import org.eclipse.dd.dsf.datamodel.IDMEvent;
import org.eclipse.dd.dsf.datamodel.IDMService;
import org.eclipse.dd.dsf.debug.service.IFormattedValues;
@ -23,20 +28,137 @@ import org.eclipse.dd.dsf.debug.service.IRegisters.IRegisterChangedDMEvent;
import org.eclipse.dd.dsf.debug.service.IRegisters.IRegisterDMContext;
import org.eclipse.dd.dsf.debug.service.IRegisters.IRegisterDMData;
import org.eclipse.dd.dsf.debug.service.IRegisters.IRegisterGroupDMContext;
import org.eclipse.dd.dsf.debug.service.IRegisters.IRegisterGroupDMData;
import org.eclipse.dd.dsf.debug.ui.DsfDebugUIPlugin;
import org.eclipse.dd.dsf.debug.ui.viewmodel.IDebugVMConstants;
import org.eclipse.dd.dsf.debug.ui.viewmodel.expression.AbstractExpressionLayoutNode;
import org.eclipse.dd.dsf.debug.ui.viewmodel.expression.WatchExpressionCellModifier;
import org.eclipse.dd.dsf.service.DsfSession;
import org.eclipse.dd.dsf.service.IDsfService;
import org.eclipse.dd.dsf.ui.viewmodel.AbstractVMProvider;
import org.eclipse.dd.dsf.ui.viewmodel.IVMContext;
import org.eclipse.dd.dsf.ui.viewmodel.VMDelta;
import org.eclipse.dd.dsf.ui.viewmodel.dm.AbstractDMVMLayoutNode;
import org.eclipse.debug.core.DebugException;
import org.eclipse.debug.core.ILaunch;
import org.eclipse.debug.core.model.IDebugTarget;
import org.eclipse.debug.core.model.IExpression;
import org.eclipse.debug.core.model.IValue;
import org.eclipse.debug.core.model.IVariable;
import org.eclipse.debug.internal.ui.viewers.model.provisional.IChildrenUpdate;
import org.eclipse.debug.internal.ui.viewers.model.provisional.IElementEditor;
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.debug.ui.actions.IWatchExpressionFactoryAdapterExtension;
import org.eclipse.jface.viewers.CellEditor;
import org.eclipse.jface.viewers.ICellModifier;
import org.eclipse.jface.viewers.TextCellEditor;
import org.eclipse.jface.viewers.TreePath;
import org.eclipse.swt.widgets.Composite;
@SuppressWarnings("restriction")
public class RegisterLayoutNode extends AbstractDMVMLayoutNode<IRegisterDMData> {
public class RegisterLayoutNode extends AbstractExpressionLayoutNode<IRegisterDMData>
implements IElementEditor
{
protected class RegisterVMC extends DMVMContext
implements IVariable
{
private IExpression fExpression;
public RegisterVMC(IDMContext<?> dmc) {
super(dmc);
}
public void setExpression(IExpression expression) {
fExpression = expression;
}
@Override
@SuppressWarnings("unchecked")
public Object getAdapter(Class adapter) {
if (fExpression != null && adapter.isAssignableFrom(fExpression.getClass())) {
return fExpression;
} else if (adapter.isAssignableFrom(IWatchExpressionFactoryAdapterExtension.class)) {
return fRegisterExpressionFactory;
} else {
return super.getAdapter(adapter);
}
}
public RegisterLayoutNode(AbstractVMProvider provider, DsfSession session) {
@Override
public boolean equals(Object other) {
if (other instanceof RegisterVMC && super.equals(other)) {
RegisterVMC otherReg = (RegisterVMC)other;
return (otherReg.fExpression == null && fExpression == null) ||
(otherReg.fExpression != null && otherReg.fExpression.equals(fExpression));
}
return false;
}
@Override
public int hashCode() {
return super.hashCode() + (fExpression != null ? fExpression.hashCode() : 0);
}
public String getName() throws DebugException { return toString(); }
public String getReferenceTypeName() throws DebugException { return ""; } //$NON-NLS-1$
public IValue getValue() throws DebugException { return null; }
public boolean hasValueChanged() throws DebugException { return false; }
public void setValue(IValue value) throws DebugException {}
public void setValue(String expression) throws DebugException {}
public boolean supportsValueModification() { return false; }
public boolean verifyValue(IValue value) throws DebugException { return false; }
public boolean verifyValue(String expression) throws DebugException { return false; }
public IDebugTarget getDebugTarget() { return null;}
public ILaunch getLaunch() { return null; }
public String getModelIdentifier() { return DsfDebugUIPlugin.PLUGIN_ID; }
}
protected class RegisterExpressionFactory implements IWatchExpressionFactoryAdapterExtension {
public boolean canCreateWatchExpression(IVariable variable) {
return variable instanceof RegisterVMC;
}
public String createWatchExpression(IVariable variable) throws CoreException {
RegisterVMC registerVmc = ((RegisterVMC)variable);
StringBuffer exprBuf = new StringBuffer();
IRegisterGroupDMContext groupDmc =
DMContexts.getAncestorOfType(registerVmc.getDMC(), IRegisterGroupDMContext.class);
if (groupDmc != null) {
IRegisterGroupDMData groupData = fSyncRegisterDataAccess.readRegisterGroup(groupDmc);
if (groupData != null) {
exprBuf.append("$$\""); //$NON-NLS-1$
exprBuf.append(groupData.getName());
exprBuf.append('"');
}
}
IRegisterDMContext registerDmc =
DMContexts.getAncestorOfType(registerVmc.getDMC(), IRegisterDMContext.class);
IRegisterDMData regData = fSyncRegisterDataAccess.readRegister(registerDmc);
if (regData != null) {
exprBuf.append('$');
exprBuf.append(regData.getName());
return exprBuf.toString();
}
return null;
}
}
private WatchExpressionCellModifier fWatchExpressionCellModifier = new WatchExpressionCellModifier();
final protected RegisterExpressionFactory fRegisterExpressionFactory = new RegisterExpressionFactory();
final private SyncRegisterDataAccess fSyncRegisterDataAccess;
public RegisterLayoutNode(AbstractVMProvider provider, DsfSession session, SyncRegisterDataAccess syncDataAccess) {
super(provider, session, IRegisters.IRegisterDMContext.class);
fSyncRegisterDataAccess = syncDataAccess;
}
protected SyncRegisterDataAccess getSyncRegisterDataAccess() {
return fSyncRegisterDataAccess;
}
/**
@ -177,12 +299,20 @@ public class RegisterLayoutNode extends AbstractDMVMLayoutNode<IRegisterDMData>
boolean weAreExtractingFormattedData = false;
for (int idx = 0; idx < localColumns.length; idx++) {
if (RegisterColumnPresentation.COL_NAME.equals(localColumns[idx])) {
if (IDebugVMConstants.COLUMN_ID__NAME.equals(localColumns[idx])) {
update.setLabel(getData().getName(), idx);
} else if (RegisterColumnPresentation.COL_VALUE.equals(localColumns[idx])) {
} else if (IDebugVMConstants.COLUMN_ID__VALUE.equals(localColumns[idx])) {
weAreExtractingFormattedData = true;
} else if (RegisterColumnPresentation.COL_DESCRIPTION.equals(localColumns[idx])) {
} else if (IDebugVMConstants.COLUMN_ID__DESCRIPTION.equals(localColumns[idx])) {
update.setLabel(getData().getDescription(), idx);
} else if (IDebugVMConstants.COLUMN_ID__EXPRESSION.equals(localColumns[idx])) {
IVMContext vmc = (IVMContext)update.getElement();
IExpression expression = (IExpression)vmc.getAdapter(IExpression.class);
if (expression != null) {
update.setLabel(expression.getExpressionText(), idx);
} else {
update.setLabel(getData().getName(), idx); //$NON-NLS-1$
}
}
}
@ -190,7 +320,7 @@ public class RegisterLayoutNode extends AbstractDMVMLayoutNode<IRegisterDMData>
update.done();
} else {
for (int idx = 0; idx < localColumns.length; idx++) {
if (RegisterColumnPresentation.COL_VALUE.equals(localColumns[idx])) {
if (IDebugVMConstants.COLUMN_ID__VALUE.equals(localColumns[idx])) {
updateFormattedRegisterValue(update, idx, dmc);
}
}
@ -225,6 +355,11 @@ public class RegisterLayoutNode extends AbstractDMVMLayoutNode<IRegisterDMData>
});
}
@Override
protected IVMContext createVMContext(IDMContext<IRegisterDMData> dmc) {
return new RegisterVMC(dmc);
}
@Override
protected int getNodeDeltaFlagsForDMEvent(IDMEvent<?> e) {
if (e instanceof IRunControl.ISuspendedDMEvent) {
@ -247,4 +382,95 @@ public class RegisterLayoutNode extends AbstractDMVMLayoutNode<IRegisterDMData>
super.buildDeltaForDMEvent(e, parent, nodeOffset, rm);
}
public int getExpressionLength(String expression) {
if (expression.charAt(0) == '$' && Character.isLetterOrDigit(expression.charAt(1))) {
int length = 1;
while( length < expression.length() && Character.isLetterOrDigit(expression.charAt(length)) ) {
length++;
}
return length;
} else {
return -1;
}
}
@Override
protected void testContextForExpression(Object element, final String expression, final DataRequestMonitor<Boolean> rm) {
if (!(element instanceof AbstractDMVMLayoutNode.DMVMContext)) {
rm.setStatus(new Status(IStatus.ERROR, DsfDebugUIPlugin.PLUGIN_ID, IDsfService.INVALID_HANDLE, "Invalid context", null)); //$NON-NLS-1$
rm.done();
return;
}
final IRegisterDMContext dmc = DMContexts.getAncestorOfType(((DMVMContext)element).getDMC(), IRegisterDMContext.class);
if (dmc == null) {
rm.setStatus(new Status(IStatus.ERROR, DsfDebugUIPlugin.PLUGIN_ID, IDsfService.INVALID_HANDLE, "Invalid context", null)); //$NON-NLS-1$
rm.done();
return;
}
((IDMService)getServicesTracker().getService(null, dmc.getServiceFilter())).getModelData(
dmc,
new DataRequestMonitor<IRegisterDMData>(getSession().getExecutor(), rm) {
@Override
protected void handleOK() {
String regName = expression.substring(1);
if (regName.equals(getData().getName())) {
rm.setData(Boolean.TRUE);
} else {
rm.setData(Boolean.FALSE);
}
rm.done();
}
});
}
@Override
protected void associateExpression(Object element, IExpression expression) {
if (element instanceof RegisterVMC) {
((RegisterVMC)element).setExpression(expression);
}
}
@Override
protected int getDeltaFlagsForExpressionPart(Object event) {
if (event instanceof IRunControl.ISuspendedDMEvent) {
return IModelDelta.CONTENT;
}
return IModelDelta.NO_CHANGE;
}
@Override
public void buildDeltaForExpression(final IExpression expression, final int elementIdx, final String expressionText, final Object event, final VMDelta parentDelta, final TreePath path, final RequestMonitor rm)
{
if (event instanceof IRunControl.ISuspendedDMEvent) {
// Mark the partent delta indicating that elements were added and/or removed.
parentDelta.addFlags(IModelDelta.CONTENT);
}
super.buildDeltaForExpression(expression, elementIdx, expressionText, event, parentDelta, path, rm);
}
@Override
protected void buildDeltaForExpressionElement(Object element, int elementIdx, Object event, VMDelta parentDelta, final RequestMonitor rm)
{
if (event instanceof IRegisters.IRegisterChangedDMEvent) {
parentDelta.addNode(element, IModelDelta.STATE);
}
super.buildDeltaForExpressionElement(element, elementIdx, event, parentDelta, rm);
}
public CellEditor getCellEditor(IPresentationContext context, String columnId, Object element, Composite parent) {
if (IDebugVMConstants.COLUMN_ID__EXPRESSION.equals(columnId)) {
return new TextCellEditor(parent);
}
return null;
}
public ICellModifier getCellModifier(IPresentationContext context, Object element) {
return fWatchExpressionCellModifier;
}
}

View file

@ -23,13 +23,17 @@ import org.eclipse.debug.internal.ui.viewers.model.provisional.IPresentationCont
*
*/
@SuppressWarnings("restriction")
public class RegisterVMProvider extends AbstractDMVMProvider {
public class RegisterVMProvider extends AbstractDMVMProvider
{
public RegisterVMProvider(AbstractVMAdapter adapter, IPresentationContext context, DsfSession session) {
super(adapter, context, session);
SyncRegisterDataAccess syncDataAccess = new SyncRegisterDataAccess();
IVMRootLayoutNode debugViewSelection = new DebugViewSelectionRootLayoutNode(this);
IVMLayoutNode registerGroupNode = new RegisterGroupLayoutNode(this, getSession());
IVMLayoutNode registerGroupNode = new RegisterGroupLayoutNode(this, getSession(), syncDataAccess);
debugViewSelection.setChildNodes(new IVMLayoutNode[] { registerGroupNode });
IVMLayoutNode registerNode = new RegisterLayoutNode(this, getSession());
IVMLayoutNode registerNode = new RegisterLayoutNode(this, getSession(), syncDataAccess);
registerGroupNode.setChildNodes(new IVMLayoutNode[] { registerNode });
setRootLayoutNode(debugViewSelection);
}

View file

@ -29,6 +29,8 @@ import org.eclipse.dd.dsf.debug.service.IRegisters.IBitFieldDMData;
import org.eclipse.dd.dsf.debug.service.IRegisters.IMnemonic;
import org.eclipse.dd.dsf.debug.service.IRegisters.IRegisterDMContext;
import org.eclipse.dd.dsf.debug.service.IRegisters.IRegisterDMData;
import org.eclipse.dd.dsf.debug.service.IRegisters.IRegisterGroupDMContext;
import org.eclipse.dd.dsf.debug.service.IRegisters.IRegisterGroupDMData;
import org.eclipse.dd.dsf.debug.ui.DsfDebugUIPlugin;
import org.eclipse.dd.dsf.service.DsfSession;
import org.eclipse.dd.dsf.service.IDsfService;
@ -390,6 +392,13 @@ public class SyncRegisterDataAccess {
}
}
public IRegisterGroupDMContext getRegisterGroupDMC(Object element) {
if (element instanceof IAdaptable) {
return (IRegisterGroupDMContext) ((IAdaptable) element).getAdapter(IRegisterGroupDMContext.class);
}
return null;
}
public IRegisterDMContext getRegisterDMC(Object element) {
if (element instanceof IAdaptable) {
return (IRegisterDMContext) ((IAdaptable) element).getAdapter(IRegisterDMContext.class);
@ -399,10 +408,99 @@ public class SyncRegisterDataAccess {
public IFormattedDataDMContext<?> getFormattedDMC(Object element) {
if (element instanceof IAdaptable) {
return (IFormattedDataDMContext) ((IAdaptable) element).getAdapter(IFormattedDataDMContext.class);
return (IFormattedDataDMContext<?>) ((IAdaptable) element).getAdapter(IFormattedDataDMContext.class);
}
return null;
}
public class GetRegisterGroupValueQuery extends Query<IRegisterGroupDMData> {
IRegisterGroupDMContext fDmc;
public GetRegisterGroupValueQuery(DsfExecutor executor, IRegisterGroupDMContext dmc) {
super(executor);
fDmc = dmc;
}
@Override
protected void execute(final DataRequestMonitor<IRegisterGroupDMData> rm) {
/*
* Guard agains the session being disposed. If session is disposed
* it could mean that the executor is shut-down, which in turn could
* mean that we can't complete the RequestMonitor argument. in that
* case, cancel to notify waiting thread.
*/
final DsfSession session = DsfSession.getSession(fDmc.getSessionId());
if (session == null) {
cancel(false);
return;
}
IRegisters service = getService(fDmc.getServiceFilter());
if (service == null) {
rm.setStatus(new Status(IStatus.ERROR, DsfDebugUIPlugin.PLUGIN_ID, IDsfService.INVALID_STATE, "Service not available", null)); //$NON-NLS-1$
rm.done();
return;
}
service.getModelData(fDmc, new DataRequestMonitor<IRegisterGroupDMData>( session.getExecutor(), rm) {
@Override
protected void handleCompleted() {
/*
* We're in another dispatch, so we must guard against
* executor shutdown again.
*/
if (!DsfSession.isSessionActive(session.getId())) {
GetRegisterGroupValueQuery.this.cancel(false);
return;
}
super.handleCompleted();
}
@Override
protected void handleOK() {
/*
* All good set return value.
*/
rm.setData(getData());
rm.done();
}
});
}
}
public IRegisterGroupDMData readRegisterGroup(Object element) {
/*
* Get the DMC and the session. If element is not an register DMC, or
* session is stale, then bail out.
*/
IRegisterGroupDMContext dmc = getRegisterGroupDMC(element);
if (dmc == null) return null;
DsfSession session = DsfSession.getSession(dmc.getSessionId());
if (session == null) return null;
/*
* Create the query to request the value from service. Note: no need to
* guard agains RejectedExecutionException, because
* DsfSession.getSession() above would only return an active session.
*/
GetRegisterGroupValueQuery query = new GetRegisterGroupValueQuery(session.getExecutor(), dmc);
session.getExecutor().execute(query);
/*
* Now we have the data, go and get it. Since the call is completed now
* the ".get()" will not suspend it will immediately return with the
* data.
*/
try {
return query.get();
} catch (InterruptedException e) {
assert false;
return null;
} catch (ExecutionException e) {
return null;
}
}
public class GetRegisterValueQuery extends Query<IRegisterDMData> {

View file

@ -0,0 +1,94 @@
/*******************************************************************************
* Copyright (c) 2006 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.dd.dsf.debug.ui.viewmodel.variable;
import org.eclipse.dd.dsf.concurrent.DataRequestMonitor;
import org.eclipse.dd.dsf.concurrent.RequestMonitor;
import org.eclipse.dd.dsf.datamodel.IDMContext;
import org.eclipse.dd.dsf.datamodel.IDMEvent;
import org.eclipse.dd.dsf.debug.service.IRegisters;
import org.eclipse.dd.dsf.debug.service.IRunControl;
import org.eclipse.dd.dsf.debug.service.IStack;
import org.eclipse.dd.dsf.debug.service.IStack.IFrameDMContext;
import org.eclipse.dd.dsf.debug.service.IStack.IVariableDMContext;
import org.eclipse.dd.dsf.debug.service.IStack.IVariableDMData;
import org.eclipse.dd.dsf.debug.ui.viewmodel.IDebugVMConstants;
import org.eclipse.dd.dsf.service.DsfSession;
import org.eclipse.dd.dsf.ui.viewmodel.AbstractVMProvider;
import org.eclipse.dd.dsf.ui.viewmodel.VMDelta;
import org.eclipse.dd.dsf.ui.viewmodel.dm.AbstractDMVMLayoutNode;
import org.eclipse.debug.internal.ui.viewers.model.provisional.IChildrenUpdate;
import org.eclipse.debug.internal.ui.viewers.model.provisional.ILabelUpdate;
import org.eclipse.debug.internal.ui.viewers.model.provisional.IModelDelta;
@SuppressWarnings("restriction")
public class LocalsLayoutNode extends AbstractDMVMLayoutNode<IVariableDMData> {
public LocalsLayoutNode(AbstractVMProvider provider, DsfSession session) {
super(provider, session, IStack.IVariableDMContext.class);
}
@Override
protected void updateElementsInSessionThread(final IChildrenUpdate update) {
if (!checkService(IRegisters.class, null, update)) return;
final IFrameDMContext frameDmc = findDmcInPath(update.getElementPath(), IFrameDMContext.class) ;
if (frameDmc != null) {
getServicesTracker().getService(IStack.class).getArguments(
frameDmc,
new DataRequestMonitor<IVariableDMContext[]>(getSession().getExecutor(), null) {
@Override
public void handleCompleted() {
if (!getStatus().isOK()) {
update.done();
return;
}
fillUpdateWithVMCs(update, getData());
update.done();
}});
} else {
handleFailedUpdate(update);
}
}
@Override
protected void fillColumnLabel(IDMContext<IVariableDMData> dmContext, IVariableDMData dmData,
String columnId, int idx, ILabelUpdate update)
{
if (IDebugVMConstants.COLUMN_ID__NAME.equals(columnId)) {
update.setLabel(dmData.getName(), idx);
} else if (IDebugVMConstants.COLUMN_ID__VALUE.equals(columnId)) {
update.setLabel(dmData.getValue(), idx);
} else {
update.setLabel("", idx); //$NON-NLS-1$
}
}
@Override
protected int getNodeDeltaFlagsForDMEvent(IDMEvent<?> e) {
if (e instanceof IRunControl.ISuspendedDMEvent) {
return IModelDelta.CONTENT;
}
return IModelDelta.NO_CHANGE;
}
@Override
protected void buildDeltaForDMEvent(IDMEvent<?> e, VMDelta parent, int nodeOffset, RequestMonitor rm) {
if (e instanceof IRunControl.ISuspendedDMEvent) {
// Create a delta that the whole register group has changed.
parent.addFlags(IModelDelta.CONTENT);
}
super.buildDeltaForDMEvent(e, parent, nodeOffset, rm);
}
}

View file

@ -0,0 +1,21 @@
package org.eclipse.dd.dsf.debug.ui.viewmodel.variable;
import org.eclipse.osgi.util.NLS;
public class MessagesForVariablesVM extends NLS {
private static final String BUNDLE_NAME = "org.eclipse.dd.dsf.debug.ui.viewmodel.variable.messages"; //$NON-NLS-1$
public static String VariableColumnPresentation_name;
public static String VariableColumnPresentation_type;
public static String VariableColumnPresentation_value;
static {
// initialize resource bundle
NLS.initializeMessages(BUNDLE_NAME, MessagesForVariablesVM.class);
}
private MessagesForVariablesVM() {
}
}

View file

@ -0,0 +1,69 @@
/*******************************************************************************
* Copyright (c) 2006 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.dd.dsf.debug.ui.viewmodel.variable;
import org.eclipse.dd.dsf.debug.ui.DsfDebugUIPlugin;
import org.eclipse.dd.dsf.debug.ui.viewmodel.IDebugVMConstants;
import org.eclipse.debug.internal.ui.viewers.model.provisional.IColumnPresentation;
import org.eclipse.debug.internal.ui.viewers.model.provisional.IPresentationContext;
import org.eclipse.jface.resource.ImageDescriptor;
/**
*
*/
@SuppressWarnings("restriction")
public class VariableColumnPresentation implements IColumnPresentation {
public static final String ID = DsfDebugUIPlugin.PLUGIN_ID + ".VARIABLES_COLUMN_PRESENTATION_ID"; //$NON-NLS-1$
// @see org.eclipse.debug.internal.ui.viewers.provisional.IColumnPresentation#init(org.eclipse.debug.internal.ui.viewers.provisional.IPresentationContext)
public void init(IPresentationContext context) {}
// @see org.eclipse.debug.internal.ui.viewers.provisional.IColumnPresentation#dispose()
public void dispose() {}
// @see org.eclipse.debug.internal.ui.viewers.provisional.IColumnPresentation#getAvailableColumns()
public String[] getAvailableColumns() {
return new String[] { IDebugVMConstants.COLUMN_ID__NAME, IDebugVMConstants.COLUMN_ID__TYPE, IDebugVMConstants.COLUMN_ID__VALUE };
}
// @see org.eclipse.debug.internal.ui.viewers.provisional.IColumnPresentation#getHeader(java.lang.String)
public String getHeader(String id) {
if (IDebugVMConstants.COLUMN_ID__NAME.equals(id)) {
return MessagesForVariablesVM.VariableColumnPresentation_name;
} else if (IDebugVMConstants.COLUMN_ID__TYPE.equals(id)) {
return MessagesForVariablesVM.VariableColumnPresentation_type;
} else if (IDebugVMConstants.COLUMN_ID__VALUE.equals(id)) {
return MessagesForVariablesVM.VariableColumnPresentation_value;
}
return null;
}
// @see org.eclipse.debug.internal.ui.viewers.provisional.IColumnPresentation#getId()
public String getId() {
return ID;
}
// @see org.eclipse.debug.internal.ui.viewers.provisional.IColumnPresentation#getImageDescriptor(java.lang.String)
public ImageDescriptor getImageDescriptor(String id) {
return null;
}
// @see org.eclipse.debug.internal.ui.viewers.provisional.IColumnPresentation#getInitialColumns()
public String[] getInitialColumns() {
return new String[] { IDebugVMConstants.COLUMN_ID__NAME, IDebugVMConstants.COLUMN_ID__TYPE, IDebugVMConstants.COLUMN_ID__VALUE };
}
// @see org.eclipse.debug.internal.ui.viewers.provisional.IColumnPresentation#isOptional()
public boolean isOptional() {
return true;
}
}

View file

@ -0,0 +1,44 @@
/*******************************************************************************
* Copyright (c) 2006 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.dd.dsf.debug.ui.viewmodel.variable;
import org.eclipse.dd.dsf.debug.ui.viewmodel.DebugViewSelectionRootLayoutNode;
import org.eclipse.dd.dsf.service.DsfSession;
import org.eclipse.dd.dsf.ui.viewmodel.AbstractVMAdapter;
import org.eclipse.dd.dsf.ui.viewmodel.IVMLayoutNode;
import org.eclipse.dd.dsf.ui.viewmodel.IVMRootLayoutNode;
import org.eclipse.dd.dsf.ui.viewmodel.dm.AbstractDMVMProvider;
import org.eclipse.debug.internal.ui.viewers.model.provisional.IColumnPresentation;
import org.eclipse.debug.internal.ui.viewers.model.provisional.IPresentationContext;
/**
*
*/
@SuppressWarnings("restriction")
public class VariableVMProvider extends AbstractDMVMProvider {
public VariableVMProvider(AbstractVMAdapter adapter, IPresentationContext context, DsfSession session) {
super(adapter, context, session);
IVMRootLayoutNode debugViewSelectionNode = new DebugViewSelectionRootLayoutNode(this);
IVMLayoutNode localsNode = new LocalsLayoutNode(this, getSession());
debugViewSelectionNode.setChildNodes(new IVMLayoutNode[] { localsNode });
setRootLayoutNode(debugViewSelectionNode);
}
@Override
public IColumnPresentation createColumnPresentation(IPresentationContext context, Object element) {
return new VariableColumnPresentation();
}
@Override
public String getColumnPresentationId(IPresentationContext context, Object element) {
return VariableColumnPresentation.ID;
}
}

View file

@ -0,0 +1,3 @@
VariableColumnPresentation_name=Name
VariableColumnPresentation_type=Type
VariableColumnPresentation_value=Value

View file

@ -82,10 +82,19 @@ abstract public class AbstractVMLayoutNode implements IVMLayoutNode {
/**
* If any of the children nodes have delta flags, that means that this
* node has to generate a delta as well.
* <p> Note: If a child node has a <code>IModelDelta.CONTENT</code> delta
* flag, it means that this flag will be added to this node's element.
* To allow for optimization change the child's <code>IModelDelta.CONTENT</code>
* flag into a <code>IModelDelta.STATE</code> flag.
*/
public int getDeltaFlags(Object e) {
int retVal = 0;
for (IVMLayoutNode childNode : getChildLayoutNodes()) {
int childNodeDeltaFlags = childNode.getDeltaFlags(e);
if ((childNodeDeltaFlags | IModelDelta.CONTENT) != 0) {
childNodeDeltaFlags &= ~IModelDelta.CONTENT;
childNodeDeltaFlags |= IModelDelta.STATE;
}
retVal |= childNode.getDeltaFlags(e);
}
return retVal;
@ -116,7 +125,7 @@ abstract public class AbstractVMLayoutNode implements IVMLayoutNode {
// Similarly, the index argument is not necessary either.
boolean mustGetElements = false;
for (int childDelta : childNodesWithDeltaFlags.values()) {
if ((childDelta & ~IModelDelta.CONTENT & ~IModelDelta.STATE) != 0) {
if ((childDelta & ~IModelDelta.STATE) != 0) {
mustGetElements = true;
}
}
@ -391,6 +400,17 @@ abstract public class AbstractVMLayoutNode implements IVMLayoutNode {
abstract public int hashCode();
}
protected TreePath getTreePathFromDelta(IModelDelta delta) {
List<Object> elementList = new LinkedList<Object>();
IModelDelta listDelta = delta;
elementList.add(0, listDelta.getElement());
while (listDelta.getParentDelta() != null) {
elementList.add(0, listDelta.getElement());
listDelta = listDelta.getParentDelta();
}
return new TreePath(elementList.toArray());
}
protected class ViewerUpdate implements IViewerUpdate {
final private RequestMonitor fRequestMonitor;
@ -486,7 +506,7 @@ abstract public class AbstractVMLayoutNode implements IVMLayoutNode {
@Override
public String toString() {
return "ElementsUpdate for all elements under parent = " + getElement(); //$NON-NLS-1$
return "VMElementsUpdate for all elements under parent = " + getElement(); //$NON-NLS-1$
}
}

View file

@ -42,8 +42,6 @@ import org.eclipse.debug.internal.ui.viewers.model.provisional.IViewerUpdate;
import org.eclipse.debug.internal.ui.viewers.provisional.AbstractModelProxy;
import org.eclipse.debug.internal.ui.viewers.provisional.IAsynchronousContentAdapter;
import org.eclipse.debug.internal.ui.viewers.provisional.IAsynchronousLabelAdapter;
import org.eclipse.jface.viewers.TreePath;
import org.eclipse.jface.viewers.Viewer;
/**
* View model provider implements the asynchronous view model functionality for
@ -66,7 +64,7 @@ abstract public class AbstractVMProvider implements IVMProvider
{
private final AbstractVMAdapter fVMAdapter;
private final IPresentationContext fPresentationContext;
private final ModelProxy fModelProxy = new ModelProxy();
private ModelProxy fModelProxy = new ModelProxy();
private boolean fDisposed = false;
/**
@ -106,7 +104,7 @@ abstract public class AbstractVMProvider implements IVMProvider
}
}
protected ModelProxy getModelProxy() {
protected synchronized ModelProxy getModelProxy() {
return fModelProxy;
}
@ -138,7 +136,7 @@ abstract public class AbstractVMProvider implements IVMProvider
Map<IVMLayoutNode,List<IHasChildrenUpdate>> nodeUpdatesMap = new HashMap<IVMLayoutNode,List<IHasChildrenUpdate>>();
for (IHasChildrenUpdate update : updates) {
// Get the VM Context for last element in path.
IVMLayoutNode layoutNode = getLayoutNodeObject(update.getElement());
IVMLayoutNode layoutNode = getLayoutNodeForElement(update.getElement());
if (layoutNode == null) {
// Stale update, most likely as a result of the layout nodes being
// changed. Just ignore it.
@ -167,8 +165,8 @@ abstract public class AbstractVMProvider implements IVMProvider
return;
}
HasElementsUpdate[][] elementsUpdates =
new HasElementsUpdate[node.getChildLayoutNodes().length][updates.length];
VMHasElementsUpdate[][] elementsUpdates =
new VMHasElementsUpdate[node.getChildLayoutNodes().length][updates.length];
for (int i = 0; i < updates.length; i ++)
{
final IHasChildrenUpdate update = updates[i];
@ -181,7 +179,7 @@ abstract public class AbstractVMProvider implements IVMProvider
// Status is OK, only if all request monitors are OK.
if (getStatus().isOK()) {
boolean isContainer = false;
for (DataRequestMonitor<Boolean> hasElementsDone : getRequestMonitors().keySet()) {
for (DataRequestMonitor<Boolean> hasElementsDone : getRequestMonitors()) {
isContainer |= hasElementsDone.getStatus().isOK() &&
hasElementsDone.getData().booleanValue();
}
@ -191,7 +189,7 @@ abstract public class AbstractVMProvider implements IVMProvider
}
};
elementsUpdates[j][i] = new HasElementsUpdate(
elementsUpdates[j][i] = new VMHasElementsUpdate(
update,
hasChildrenMultiRequestMon.add(
new DataRequestMonitor<Boolean>(getExecutor(), null) {
@ -214,7 +212,7 @@ abstract public class AbstractVMProvider implements IVMProvider
if (update.isCanceled()) continue;
getChildrenCountsForNode(
update, update.getElementPath(),
update,
new DataRequestMonitor<Integer[]>(getExecutor(), null) {
@Override
protected void handleCompleted() {
@ -236,7 +234,7 @@ abstract public class AbstractVMProvider implements IVMProvider
public void update(IChildrenUpdate[] updates) {
for (final IChildrenUpdate update : updates) {
getChildrenCountsForNode(
update, update.getElementPath(),
update,
new DataRequestMonitor<Integer[]>(getExecutor(), null) {
@Override
protected void handleCompleted() {
@ -251,11 +249,11 @@ abstract public class AbstractVMProvider implements IVMProvider
}
private void getChildrenCountsForNode(IViewerUpdate update, TreePath elementPath, final DataRequestMonitor<Integer[]> rm) {
private void getChildrenCountsForNode(IViewerUpdate update, final DataRequestMonitor<Integer[]> rm) {
if (isDisposed()) return;
// Get the VM Context for last element in path.
final IVMLayoutNode layoutNode = getLayoutNodeObject(update.getElement());
final IVMLayoutNode layoutNode = getLayoutNodeForElement(update.getElement());
if (layoutNode == null) {
// Stale update. Just ignore.
rm.setStatus(new Status(
@ -294,7 +292,7 @@ abstract public class AbstractVMProvider implements IVMProvider
for (int i = 0; i < childNodes.length; i++) {
final int nodeIndex = i;
childNodes[i].updateElementCount(
new ElementsCountUpdate(
new VMElementsCountUpdate(
update,
childrenCountMultiReqMon.add(
new DataRequestMonitor<Integer>(getExecutor(), null) {
@ -308,14 +306,13 @@ abstract public class AbstractVMProvider implements IVMProvider
super.handleCompleted();
childrenCountMultiReqMon.requestMonitorDone(this);
}
}),
elementPath)
}))
);
}
}
private void updateChildrenWithCounts(final IChildrenUpdate update, Integer[] nodeElementCounts) {
final IVMLayoutNode layoutNode = getLayoutNodeObject(update.getElement());
final IVMLayoutNode layoutNode = getLayoutNodeForElement(update.getElement());
if (layoutNode == null) {
// Stale update. Just ignore.
if (!update.isCanceled()) update.done();
@ -347,18 +344,22 @@ abstract public class AbstractVMProvider implements IVMProvider
if (updateStartIdx <= nodeEndIdx && updateEndIdx > nodeStartIdx) {
final int elementsStartIdx = Math.max(updateStartIdx - nodeStartIdx, 0);
final int elementsEndIdx = Math.min(updateEndIdx - nodeStartIdx, nodeElementCounts[i]);
layoutNodes[i].updateElements(
new ElementsUpdate(
update,
elementsMultiRequestMon.add(new RequestMonitor(getExecutor(), null) {
@Override
protected void handleCompleted() {
elementsMultiRequestMon.requestMonitorDone(this);
}
}),
nodeStartIdx, elementsStartIdx, elementsEndIdx - elementsStartIdx)
);
final int elementsLength = elementsEndIdx - elementsStartIdx;
if (elementsLength > 0) {
layoutNodes[i].updateElements(
new VMElementsUpdate(
update, elementsStartIdx, elementsLength,
elementsMultiRequestMon.add(new DataRequestMonitor<List<Object>>(getExecutor(), null) {
@Override
protected void handleCompleted() {
for (int i = 0; i < elementsLength; i++) {
update.setChild(getData().get(i), elementsStartIdx + nodeStartIdx + i);
}
elementsMultiRequestMon.requestMonitorDone(this);
}
}))
);
}
}
}
@ -378,6 +379,9 @@ abstract public class AbstractVMProvider implements IVMProvider
if (getRootLayoutNode() != null &&
element.equals(getRootLayoutNode().getRootObject()))
{
synchronized(this) {
fModelProxy = new ModelProxy();
}
return fModelProxy;
}
return null;
@ -429,7 +433,7 @@ abstract public class AbstractVMProvider implements IVMProvider
* @return parent VMC, if null it indicates that the object did not originate
* from this view or is stale.
*/
private IVMLayoutNode getLayoutNodeObject(Object element) {
protected IVMLayoutNode getLayoutNodeForElement(Object element) {
/*
* First check to see if the parent object is the root object of the
* hierarchy. If that's the case, then retrieve the correcponding
@ -474,14 +478,39 @@ abstract public class AbstractVMProvider implements IVMProvider
}
protected void handleEvent(final Object event) {
// We're in session's executor thread. Re-dispach to VM Adapter
// executor thread and then call root layout node.
try {
getExecutor().execute(new Runnable() {
public void run() {
if (isDisposed()) return;
IVMRootLayoutNode rootLayoutNode = getRootLayoutNode();
if (rootLayoutNode != null && rootLayoutNode.getDeltaFlags(event) != 0) {
rootLayoutNode.createDelta(
event,
new DataRequestMonitor<IModelDelta>(getExecutor(), null) {
@Override
public void handleCompleted() {
if (getStatus().isOK()) {
getModelProxy().fireModelChangedNonDispatch(getData());
}
}
@Override public String toString() {
return "Result of a delta for event: '" + event.toString() + "' in VMP: '" + AbstractVMProvider.this + "'" + "\n" + getData().toString(); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
}
});
}
}});
} catch (RejectedExecutionException e) {
// Ignore. This exception could be thrown if the provider is being
// shut down.
}
}
@ThreadSafe
protected class ModelProxy extends AbstractModelProxy {
/**
* Counter for whether the model proxy is currently installed in the viewer.
* Data model events are processed only if the model proxy is active.
*/
private int fProxyActive = 0;
/**
* Scheduling rule for running the update jobs.
*/
@ -490,25 +519,12 @@ abstract public class AbstractVMProvider implements IVMProvider
public boolean isConflicting(ISchedulingRule rule) { return rule == this; }
};
@Override
public void installed(Viewer viewer) {
fProxyActive++;
}
@Override
public void dispose() {
fProxyActive--;
super.dispose();
}
/**
* Fires given delta using a job. Processing the delta on the dispatch
* thread can lead to dead-locks.
* @param delta
*/
public void fireModelChangedNonDispatch(final IModelDelta delta) {
if (fProxyActive <= 0) return;
Job job = new Job("Processing view model delta.") { //$NON-NLS-1$
@Override
protected IStatus run(IProgressMonitor monitor) {
@ -522,125 +538,4 @@ abstract public class AbstractVMProvider implements IVMProvider
}
}
class ViewerUpdate implements IViewerUpdate {
private IStatus fStatus;
final private RequestMonitor fRequestMonitor;
final protected IViewerUpdate fClientUpdate;
public ViewerUpdate(IViewerUpdate clientUpdate, RequestMonitor requestMonitor) {
fRequestMonitor = requestMonitor;
fClientUpdate = clientUpdate;
}
public Object getElement() { return fClientUpdate.getElement(); }
public TreePath getElementPath() { return fClientUpdate.getElementPath(); }
public IPresentationContext getPresentationContext() { return fClientUpdate.getPresentationContext(); }
public IStatus getStatus() { return fStatus; }
public void setStatus(IStatus status) { fStatus = status; }
public boolean isCanceled() { return fClientUpdate.isCanceled(); }
public void cancel() {
fClientUpdate.cancel();
}
public void done() {
try {
fRequestMonitor.done();
} catch (RejectedExecutionException e) { // Ignore
}
}
}
class HasElementsUpdate extends ViewerUpdate implements IHasChildrenUpdate {
final private DataRequestMonitor<Boolean> fHasElemsRequestMonitor;
HasElementsUpdate(IHasChildrenUpdate clientUpdate, DataRequestMonitor<Boolean> rm) {
super(clientUpdate, rm);
fHasElemsRequestMonitor = rm;
}
@Override
public TreePath getElementPath() {
return ((IHasChildrenUpdate)fClientUpdate).getElementPath();
}
public void setHasChilren(boolean hasChildren) {
fHasElemsRequestMonitor.setData(hasChildren);
}
@Override
public void done() {
assert fHasElemsRequestMonitor.getData() != null || !fHasElemsRequestMonitor.getStatus().isOK();
super.done();
}
}
class ElementsCountUpdate extends ViewerUpdate implements IChildrenCountUpdate {
final private DataRequestMonitor<Integer> fCountRequestMonitor;
final private TreePath fElementPath;
ElementsCountUpdate(IViewerUpdate clientUpdate, DataRequestMonitor<Integer> rm, TreePath elementPath) {
super(clientUpdate, rm);
fElementPath = elementPath;
fCountRequestMonitor = rm;
}
@Override
public TreePath getElementPath() {
return fElementPath;
}
public void setChildCount(int count) {
fCountRequestMonitor.setData(count);
}
@Override
public void done() {
assert fCountRequestMonitor.getData() != null || !fCountRequestMonitor.getStatus().isOK();
super.done();
}
}
class ElementsUpdate extends ViewerUpdate implements IChildrenUpdate {
private final int fClientOffset;
private final int fOffset;
private final int fLength;
ElementsUpdate(IChildrenUpdate clientUpdate, RequestMonitor requestMonitor, int clientOffset, int offset, int length) {
super(clientUpdate, requestMonitor);
fClientOffset = clientOffset;
fOffset = offset;
fLength = length;
}
public int getOffset() {
return fOffset;
}
public int getLength() {
return fLength;
}
@Override
public TreePath getElementPath() {
return ((IChildrenUpdate)fClientUpdate).getElementPath();
}
public void setChild(Object child, int offset) {
if (offset >= fOffset && offset < (fOffset + fLength)) {
((IChildrenUpdate)fClientUpdate).setChild(child, fClientOffset + offset);
}
}
@Override
public String toString() {
return "ElementsUpdate for elements under parent = " + getElement() + ", in range " + getOffset() + " -> " + (getOffset() + getLength()); //$NON-NLS-1$ //$NON-NLS-2$//$NON-NLS-3$
}
}
}

View file

@ -0,0 +1,41 @@
/*******************************************************************************
* Copyright (c) 2007 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.dd.dsf.ui.viewmodel;
import org.eclipse.dd.dsf.concurrent.DataRequestMonitor;
import org.eclipse.debug.internal.ui.viewers.model.provisional.IChildrenCountUpdate;
import org.eclipse.debug.internal.ui.viewers.model.provisional.IElementContentProvider;
import org.eclipse.debug.internal.ui.viewers.model.provisional.IViewerUpdate;
/**
* Helper class implementation of an update object to use with IElementContentProvider.
* @see IElementContentProvider
*/
@SuppressWarnings("restriction")
public class VMElementsCountUpdate extends VMViewerUpdate implements IChildrenCountUpdate {
final private DataRequestMonitor<Integer> fCountRequestMonitor;
public VMElementsCountUpdate(IViewerUpdate clientUpdate, DataRequestMonitor<Integer> rm) {
super(clientUpdate, rm);
fCountRequestMonitor = rm;
}
public void setChildCount(int count) {
fCountRequestMonitor.setData(count);
}
@Override
public void done() {
assert fCountRequestMonitor.getData() != null || !fCountRequestMonitor.getStatus().isOK();
super.done();
}
}

View file

@ -0,0 +1,77 @@
/*******************************************************************************
* Copyright (c) 2007 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.dd.dsf.ui.viewmodel;
import java.util.ArrayList;
import java.util.List;
import org.eclipse.dd.dsf.concurrent.DataRequestMonitor;
import org.eclipse.debug.internal.ui.viewers.model.provisional.IChildrenUpdate;
import org.eclipse.debug.internal.ui.viewers.model.provisional.IElementContentProvider;
/**
* Helper class implementation of an update object to use with IElementContentProvider.
* @see IElementContentProvider
*/
@SuppressWarnings("restriction")
public class VMElementsUpdate extends VMViewerUpdate implements IChildrenUpdate {
private final int fOffset;
private final int fLength;
private final List<Object> fElements;
public VMElementsUpdate(IChildrenUpdate clientUpdate, int offset, int length, DataRequestMonitor<List<Object>> requestMonitor) {
super(clientUpdate, requestMonitor);
fOffset = offset;
fLength = length;
fElements = length > 0 ? new ArrayList<Object>(length) : new ArrayList<Object>();
}
public int getOffset() {
return fOffset;
}
public int getLength() {
return fLength;
}
public void setChild(Object element, int offset) {
// Calculate the index in array based on configured offset.
int idx = offset - (fOffset > 0 ? fOffset : 0);
// To make sure that index is in valid range.
if (idx < 0 || (fLength > 0 && idx >= fLength)) return;
// Increase the list size if needed.
ensureElementsSize(idx + 1);
// Finally set the element in elements list.
fElements.set(idx, element);
}
private void ensureElementsSize(int size) {
while (fElements.size() < size) {
fElements.add(null);
}
}
@Override
public String toString() {
return "VMElementsUpdate for elements under parent = " + getElement() + ", in range " + getOffset() + " -> " + (getOffset() + getLength()); //$NON-NLS-1$ //$NON-NLS-2$//$NON-NLS-3$
}
@Override
public void done() {
@SuppressWarnings("unchecked")
DataRequestMonitor<List<Object>> rm = (DataRequestMonitor<List<Object>>)fRequestMonitor;
rm.setData(fElements);
super.done();
}
}

View file

@ -0,0 +1,40 @@
/*******************************************************************************
* Copyright (c) 2007 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.dd.dsf.ui.viewmodel;
import org.eclipse.dd.dsf.concurrent.DataRequestMonitor;
import org.eclipse.debug.internal.ui.viewers.model.provisional.IElementContentProvider;
import org.eclipse.debug.internal.ui.viewers.model.provisional.IHasChildrenUpdate;
/**
* Helper class implementation of an update object to use with IElementContentProvider.
* @see IElementContentProvider
*/
@SuppressWarnings("restriction")
public class VMHasElementsUpdate extends VMViewerUpdate implements IHasChildrenUpdate {
final private DataRequestMonitor<Boolean> fHasElemsRequestMonitor;
public VMHasElementsUpdate(IHasChildrenUpdate clientUpdate, DataRequestMonitor<Boolean> rm) {
super(clientUpdate, rm);
fHasElemsRequestMonitor = rm;
}
public void setHasChilren(boolean hasChildren) {
fHasElemsRequestMonitor.setData(hasChildren);
}
@Override
public void done() {
assert fHasElemsRequestMonitor.getData() != null || !fHasElemsRequestMonitor.getStatus().isOK();
super.done();
}
}

View file

@ -0,0 +1,54 @@
/*******************************************************************************
* Copyright (c) 2007 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.dd.dsf.ui.viewmodel;
import java.util.concurrent.RejectedExecutionException;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.dd.dsf.concurrent.RequestMonitor;
import org.eclipse.debug.internal.ui.viewers.model.provisional.IElementContentProvider;
import org.eclipse.debug.internal.ui.viewers.model.provisional.IPresentationContext;
import org.eclipse.debug.internal.ui.viewers.model.provisional.IViewerUpdate;
import org.eclipse.jface.viewers.TreePath;
/**
* Helper class implementation of an update object to use with IElementContentProvider.
* @see IElementContentProvider
*/
@SuppressWarnings("restriction")
public class VMViewerUpdate implements IViewerUpdate {
final protected RequestMonitor fRequestMonitor;
final protected IViewerUpdate fClientUpdate;
public VMViewerUpdate(IViewerUpdate clientUpdate, RequestMonitor requestMonitor) {
fRequestMonitor = requestMonitor;
fClientUpdate = clientUpdate;
}
public Object getElement() { return fClientUpdate.getElement(); }
public TreePath getElementPath() { return fClientUpdate.getElementPath(); }
public IPresentationContext getPresentationContext() { return fClientUpdate.getPresentationContext(); }
public IStatus getStatus() { return fRequestMonitor.getStatus(); }
public void setStatus(IStatus status) { fRequestMonitor.setStatus(status); }
public boolean isCanceled() { return fClientUpdate.isCanceled(); }
public void cancel() {
fClientUpdate.cancel();
}
public void done() {
try {
fRequestMonitor.done();
} catch (RejectedExecutionException e) { // Ignore
}
}
}

View file

@ -452,9 +452,9 @@ abstract public class AbstractDMVMLayoutNode<V extends IDMData> extends Abstract
callChildNodesToBuildDelta(childNodeDeltas, delta, event, requestMonitor);
}
} else {
// The for this node was not found in the event. Call the
// The DMC for this node was not found in the event. Call the
// super-class to resort to the default behavior which may add a
// delta node for every element in this node.
// delta for every element in this node.
super.buildDelta(event, parentDelta, nodeOffset, requestMonitor);
}
}

View file

@ -13,15 +13,12 @@ package org.eclipse.dd.dsf.ui.viewmodel.dm;
import java.util.concurrent.RejectedExecutionException;
import org.eclipse.dd.dsf.concurrent.ConfinedToDsfExecutor;
import org.eclipse.dd.dsf.concurrent.DataRequestMonitor;
import org.eclipse.dd.dsf.datamodel.IDMEvent;
import org.eclipse.dd.dsf.service.DsfServiceEventHandler;
import org.eclipse.dd.dsf.service.DsfSession;
import org.eclipse.dd.dsf.ui.viewmodel.AbstractVMAdapter;
import org.eclipse.dd.dsf.ui.viewmodel.AbstractVMProvider;
import org.eclipse.dd.dsf.ui.viewmodel.IVMLayoutNode;
import org.eclipse.dd.dsf.ui.viewmodel.IVMRootLayoutNode;
import org.eclipse.debug.internal.ui.viewers.model.provisional.IModelDelta;
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.provisional.IAsynchronousContentAdapter;
@ -111,33 +108,6 @@ abstract public class AbstractDMVMProvider extends AbstractVMProvider
public void eventDispatched(final IDMEvent<?> event) {
if (isDisposed()) return;
// We're in session's executor thread. Re-dispach to VM Adapter
// executor thread and then call root layout node.
try {
getExecutor().execute(new Runnable() {
public void run() {
if (isDisposed()) return;
IVMRootLayoutNode rootLayoutNode = getRootLayoutNode();
if (rootLayoutNode != null && rootLayoutNode.getDeltaFlags(event) != 0) {
rootLayoutNode.createDelta(
event,
new DataRequestMonitor<IModelDelta>(getExecutor(), null) {
@Override
public void handleCompleted() {
if (getStatus().isOK()) {
getModelProxy().fireModelChangedNonDispatch(getData());
}
}
@Override public String toString() {
return "Result of a delta for event: '" + event.toString() + "' in VMP: '" + AbstractDMVMProvider.this + "'" + "\n" + getData().toString(); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
}
});
}
}});
} catch (RejectedExecutionException e) {
// Ignore. This exception could be thrown if the provider is being
// shut down.
}
handleEvent(event);
}
}

View file

@ -0,0 +1,61 @@
/*******************************************************************************
* Copyright (c) 2006 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.dd.dsf.concurrent;
import org.eclipse.core.runtime.MultiStatus;
import org.eclipse.dd.dsf.DsfPlugin;
/**
* Utility class to collect multiple request monitor results of commands
* that are initiated simultaneously. The usage is as follows:
* <pre>
* final MultiRequestMonitor multiRequestMon = new MultiRequestMonitor(fExecutor, null) {
* public void handleCompleted() {
* System.out.println("All complete, errors=" + !getStatus().isOK());
* }
* };
*
* for (int i = 0; i < 10; i++) {
* service.call(i, multiRequestMon.addRequestMonitor(
* new RequestMonitor(fExecutor, null) {
* public void handleCompleted() {
* System.out.println(Integer.toString(i) + " complete");
* multiRequestMon.requestMonitorDone(this);
* }
* }));
* }
* </pre>
*/
public class CountingRequestMonitor extends RequestMonitor {
private int fDoneCounter;
public CountingRequestMonitor(DsfExecutor executor, RequestMonitor parentRequestMonitor) {
super(executor, parentRequestMonitor);
setStatus(new MultiStatus(DsfPlugin.PLUGIN_ID, 0, "Collective status for set of sub-operations.", null)); //$NON-NLS-1$
}
public void setCount(int count) {
fDoneCounter = count;
}
@Override
public synchronized void done() {
fDoneCounter--;
if (fDoneCounter <= 0) {
super.done();
}
}
@Override
public String toString() {
return "Multi-RequestMonitor: " + getStatus().toString(); //$NON-NLS-1$
}
}

View file

@ -16,7 +16,7 @@ package org.eclipse.dd.dsf.concurrent;
*
* @param V The type of the data object that this monitor handles.
*/
public abstract class DataRequestMonitor<V> extends RequestMonitor {
public class DataRequestMonitor<V> extends RequestMonitor {
/** Data object reference */
private V fData;

View file

@ -11,6 +11,8 @@
package org.eclipse.dd.dsf.concurrent;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import org.eclipse.core.runtime.MultiStatus;
@ -37,8 +39,9 @@ import org.eclipse.dd.dsf.DsfPlugin;
* }
* </pre>
*/
public abstract class MultiRequestMonitor<V extends RequestMonitor> extends RequestMonitor {
private Map<V,Boolean> fRequestMonitors = new HashMap<V,Boolean>();
public class MultiRequestMonitor<V extends RequestMonitor> extends RequestMonitor {
private List<V> fRequestMonitorList = new LinkedList<V>();
private Map<V,Boolean> fStatusMap = new HashMap<V,Boolean>();
private int fDoneCounter;
public MultiRequestMonitor(DsfExecutor executor, RequestMonitor parentRequestMonitor) {
@ -55,8 +58,9 @@ public abstract class MultiRequestMonitor<V extends RequestMonitor> extends Requ
* inlined in service method calls
*/
public <T extends V> T add(T rm) {
assert !fRequestMonitors.containsKey(rm);
fRequestMonitors.put(rm, false);
assert !fStatusMap.containsKey(rm);
fRequestMonitorList.add(rm);
fStatusMap.put(rm, false);
fDoneCounter++;
return rm;
}
@ -70,23 +74,29 @@ public abstract class MultiRequestMonitor<V extends RequestMonitor> extends Requ
*/
public void requestMonitorDone(V requestMonitor) {
((MultiStatus)getStatus()).merge(requestMonitor.getStatus());
assert fRequestMonitors.containsKey(requestMonitor);
fRequestMonitors.put(requestMonitor, true);
assert fStatusMap.containsKey(requestMonitor);
fStatusMap.put(requestMonitor, true);
assert fDoneCounter > 0;
fDoneCounter--;
if (fDoneCounter == 0) {
assert !fRequestMonitors.containsValue(false);
assert !fStatusMap.containsValue(false);
super.done();
}
}
/**
* Returns the map of RequestMonitor callbacks. Access to this data is provided
* in case overriding classes need access to the collected data in the
* request monitors.
* @return map of the request monitors
* Returns the list of requested monitors, sorted in order as they were added.
*/
public Map<V,Boolean> getRequestMonitors() { return fRequestMonitors; }
public List<V> getRequestMonitors() {
return fRequestMonitorList;
}
/**
* Returns true if given monitor is finished.
*/
public boolean isRequestMonitorDone(V rm) {
return fStatusMap.get(rm);
}
@Override
public String toString() {