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

Finished refactoring view model adapter, cleaned up warnings, added column support (bugs 159161, 159679, 161981).

This commit is contained in:
Pawel Piech 2006-11-10 00:18:15 +00:00
parent 56e3520f7a
commit 91d2328263
20 changed files with 573 additions and 219 deletions

View file

@ -17,5 +17,7 @@ Require-Bundle: org.eclipse.ui,
org.eclipse.dd.dsf.debug
Eclipse-LazyStart: true
Export-Package:
org.eclipse.dd.dsf.debug.ui.viewmodel
org.eclipse.dd.dsf.debug.ui.viewmodel,
org.eclipse.dd.dsf.debug.ui.viewmodel.register,
org.eclipse.dd.dsf.debug.ui.viewmodel.launch
Bundle-RequiredExecutionEnvironment: J2SE-1.5

View file

@ -10,7 +10,7 @@ import org.osgi.framework.BundleContext;
public class DsfDebugUIPlugin extends AbstractUIPlugin {
// The plug-in ID
public static final String PLUGIN_ID = "org.eclipse.dd.dsf.debug.ui";
public static final String PLUGIN_ID = "org.eclipse.dd.dsf.debug.ui"; //$NON-NLS-1$
// The shared instance
private static DsfDebugUIPlugin plugin;

View file

@ -47,9 +47,9 @@ public class DebugViewSelectionRootLayoutNode extends AbstractVMRootLayoutNode
}
@Override
public void sessionDispose() {
public void dispose() {
DebugUITools.getDebugContextManager().removeDebugContextListener(this);
super.sessionDispose();
super.dispose();
}
/**

View file

@ -8,10 +8,11 @@
* Contributors:
* Wind River Systems - initial API and implementation
*******************************************************************************/
package org.eclipse.dd.dsf.debug.ui.viewmodel;
package org.eclipse.dd.dsf.debug.ui.viewmodel.launch;
import org.eclipse.dd.dsf.concurrent.DsfRunnable;
import org.eclipse.dd.dsf.concurrent.GetDataDone;
import org.eclipse.dd.dsf.concurrent.ThreadSafe;
import org.eclipse.dd.dsf.service.DsfSession;
import org.eclipse.dd.dsf.ui.viewmodel.IVMRootLayoutNode;
import org.eclipse.dd.dsf.ui.viewmodel.VMProvider;
@ -25,11 +26,11 @@ import org.eclipse.debug.internal.ui.viewers.provisional.IModelDelta;
*
*/
@SuppressWarnings("restriction")
public class DebugViewModelProvider extends VMProvider
public class LaunchViewModelProvider extends VMProvider
implements IDebugEventSetListener
{
public DebugViewModelProvider(DsfSession session, IVMRootLayoutNode rootLayoutNode) {
@ThreadSafe
public LaunchViewModelProvider(DsfSession session, IVMRootLayoutNode rootLayoutNode) {
super(session, rootLayoutNode);
DebugPlugin.getDefault().addDebugEventListener(this);
}
@ -50,7 +51,7 @@ public class DebugViewModelProvider extends VMProvider
* Just like with DMC events, go through all the layout nodes and
* collect delta information for the received event.
*/
if (getRootLayoutNode().hasDeltaFlags(event)) {
if (getRootLayoutNode() != null && getRootLayoutNode().hasDeltaFlags(event)) {
getRootLayoutNode().createDelta(event, new GetDataDone<IModelDelta>() {
public void run() {
if (getStatus().isOK()) {
@ -61,10 +62,9 @@ public class DebugViewModelProvider extends VMProvider
}
}
@Override
public void sessionDispose() {
public void dispose() {
DebugPlugin.getDefault().removeDebugEventListener(this);
super.sessionDispose();
super.dispose();
}
}

View file

@ -8,7 +8,7 @@
* Contributors:
* Wind River Systems - initial API and implementation
*******************************************************************************/
package org.eclipse.dd.dsf.debug.ui.viewmodel;
package org.eclipse.dd.dsf.debug.ui.viewmodel.launch;
import org.eclipse.core.runtime.MultiStatus;
import org.eclipse.dd.dsf.concurrent.Done;
@ -34,7 +34,7 @@ import org.eclipse.jface.resource.ImageDescriptor;
@SuppressWarnings("restriction")
public class StackFramesLayoutNode extends DMContextVMLayoutNode {
public class StackFramesLayoutNode extends DMContextVMLayoutNode<IStack.IFrameDMData> {
public IVMContext[] fCachedOldFramesVMCs;
@ -72,7 +72,7 @@ public class StackFramesLayoutNode extends DMContextVMLayoutNode {
if (getServicesTracker().getService(IRunControl.class).isStepping(execDmc)) {
getElementsTopStackFrameOnly(parentVmc, done);
} else {
propagateError(getExecutor(), done, "Failed retrieving stack frames");
propagateError(getExecutor(), done, "Failed retrieving stack frames"); //$NON-NLS-1$
}
return;
}
@ -95,7 +95,7 @@ public class StackFramesLayoutNode extends DMContextVMLayoutNode {
getServicesTracker().getService(IStack.class).getTopFrame(
execDmc,
new GetDataDone<IFrameDMContext>() { public void run() {
if (propagateError(getExecutor(), done, "Failed retrieving top stack frame")) return;
if (propagateError(getExecutor(), done, "Failed retrieving top stack frame")) return; //$NON-NLS-1$
IVMContext topFrameVmc = new DMContextVMContext(parentVmc, getData());
// If there are old frames cached, use them and only substitute the top frame object. Otherwise, create
@ -110,7 +110,7 @@ public class StackFramesLayoutNode extends DMContextVMLayoutNode {
}});
}
public void retrieveLabel(IVMContext vmc, final ILabelRequestMonitor result) {
public void retrieveLabel(IVMContext vmc, final ILabelRequestMonitor result, String[] columns) {
final IExecutionDMContext execDmc = findDmcInVmc(vmc, IExecutionDMContext.class);
if (execDmc == null || getServicesTracker().getService(IStack.class) == null || getServicesTracker().getService(IRunControl.class) == null) {
result.done();
@ -142,9 +142,9 @@ public class StackFramesLayoutNode extends DMContextVMLayoutNode {
// If failed set a dummy label, and only propagate the
// error if we are not stepping, since that would be a
// common cause of failure.
result.setLabels(new String[] { "..." });
result.setLabels(new String[] { "..." }); //$NON-NLS-1$
if (!getServicesTracker().getService(IRunControl.class).isStepping(execDmc)) {
MultiStatus status = new MultiStatus(DsfDebugUIPlugin.PLUGIN_ID, 0, "Failed to retrieve stack frame label", null);
MultiStatus status = new MultiStatus(DsfDebugUIPlugin.PLUGIN_ID, 0, "Failed to retrieve stack frame label", null); //$NON-NLS-1$
status.add(getStatus());
result.setStatus(status);
}
@ -164,22 +164,22 @@ public class StackFramesLayoutNode extends DMContextVMLayoutNode {
// Add the function name
if (getData().getFunction() != null && getData().getFunction().length() != 0) {
label.append(" ");
label.append(" "); //$NON-NLS-1$
label.append(getData().getFunction());
label.append("()");
label.append("()"); //$NON-NLS-1$
}
// Add full file name
if (getData().getFile() != null && getData().getFile().length() != 0) {
label.append(" at ");
label.append(" at "); //$NON-NLS-1$
label.append(getData().getFile());
}
// Add line number
if (getData().getLine() >= 0) {
label.append(":");
label.append(":"); //$NON-NLS-1$
label.append(getData().getLine());
label.append(" ");
label.append(" "); //$NON-NLS-1$
}
// Add the address
@ -191,7 +191,7 @@ public class StackFramesLayoutNode extends DMContextVMLayoutNode {
}});
}
public boolean hasDeltaFlagsForDMEvent(IDMEvent e) {
public boolean hasDeltaFlagsForDMEvent(IDMEvent<?> e) {
// This node generates delta if the timers have changed, or if the
// label has changed.
return e instanceof IRunControl.ISuspendedDMEvent ||
@ -200,7 +200,7 @@ public class StackFramesLayoutNode extends DMContextVMLayoutNode {
super.hasDeltaFlagsForDMEvent(e);
}
public void buildDeltaForDMEvent(final IDMEvent e, final VMDelta parent, final Done done) {
public void buildDeltaForDMEvent(final IDMEvent<?> e, final VMDelta parent, final Done done) {
if (getServicesTracker().getService(IStack.class) == null || getServicesTracker().getService(IRunControl.class) == null) {
// Required services have not initialized yet. Ignore the event.
super.buildDeltaForDMEvent(e, parent, done);

View file

@ -8,7 +8,7 @@
* Contributors:
* Wind River Systems - initial API and implementation
*******************************************************************************/
package org.eclipse.dd.dsf.debug.ui.viewmodel;
package org.eclipse.dd.dsf.debug.ui.viewmodel.launch;
import org.eclipse.dd.dsf.concurrent.DoneCollector;
import org.eclipse.dd.dsf.concurrent.DsfExecutor;
@ -87,7 +87,7 @@ public class StandardLaunchRootLayoutNode extends AbstractVMRootLayoutNode
*/
final DoneCollector doneCollector = new DoneCollector(getExecutor()) {
public void run() {
if (propagateError(getExecutor(), done, "Failed to generate child deltas.")) return;
if (propagateError(getExecutor(), done, "Failed to generate child deltas.")) return; //$NON-NLS-1$
done.setData(delta);
getExecutor().execute(done);
}

View file

@ -8,7 +8,7 @@
* Contributors:
* Wind River Systems - initial API and implementation
*******************************************************************************/
package org.eclipse.dd.dsf.debug.ui.viewmodel;
package org.eclipse.dd.dsf.debug.ui.viewmodel.launch;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
@ -54,9 +54,9 @@ public class StandardProcessLayoutNode extends AbstractVMLayoutNode {
}
public IVMContext getParent() { return fParentVmc; }
public IVMLayoutNode getLayoutNode() { return StandardProcessLayoutNode.this; }
public Object getAdapter(Class adapter) { return fProcess.getAdapter(adapter); }
public String toString() { return "IProcess " + fProcess.toString(); }
public IVMLayoutNode getLayoutNode() { return StandardProcessLayoutNode.this; }
@SuppressWarnings("unchecked") public Object getAdapter(Class adapter) { return fProcess.getAdapter(adapter); }
public String toString() { return "IProcess " + fProcess.toString(); } //$NON-NLS-1$
public String getAttribute(String key) { return fProcess.getAttribute(key); }
public int getExitValue() throws DebugException { return fProcess.getExitValue(); }
@ -85,7 +85,7 @@ public class StandardProcessLayoutNode extends AbstractVMLayoutNode {
* layout is misconfigured.
*/
assert false;
done.setStatus(new Status(IStatus.ERROR, DsfDebugUIPlugin.PLUGIN_ID, IDsfService.INTERNAL_ERROR, "Can't get list of processes, because there is no launch.", null));
done.setStatus(new Status(IStatus.ERROR, DsfDebugUIPlugin.PLUGIN_ID, IDsfService.INTERNAL_ERROR, "Can't get list of processes, because there is no launch.", null)); //$NON-NLS-1$
getExecutor().execute(done);
return;
}
@ -108,7 +108,7 @@ public class StandardProcessLayoutNode extends AbstractVMLayoutNode {
ILaunch launch = findLaunch(parentVmc);
if (launch == null) {
assert false;
done.setStatus(new Status(IStatus.ERROR, DsfDebugUIPlugin.PLUGIN_ID, IDsfService.INTERNAL_ERROR, "Can't get list of processes, because there is no launch.", null));
done.setStatus(new Status(IStatus.ERROR, DsfDebugUIPlugin.PLUGIN_ID, IDsfService.INTERNAL_ERROR, "Can't get list of processes, because there is no launch.", null)); //$NON-NLS-1$
getExecutor().execute(done);
return;
}
@ -118,7 +118,7 @@ public class StandardProcessLayoutNode extends AbstractVMLayoutNode {
}
// @see org.eclipse.dd.dsf.ui.viewmodel.IViewModelLayoutNode#retrieveLabel(org.eclipse.dd.dsf.ui.viewmodel.IVMContext, org.eclipse.debug.internal.ui.viewers.provisional.ILabelRequestMonitor)
public void retrieveLabel(IVMContext vmc, ILabelRequestMonitor result) {
public void retrieveLabel(IVMContext vmc, ILabelRequestMonitor result, String[] columns) {
/*
* The implementation of IAdapterFactory that uses this node should not

View file

@ -0,0 +1,20 @@
package org.eclipse.dd.dsf.debug.ui.viewmodel.register;
import org.eclipse.osgi.util.NLS;
public class MessagesForRegisterVM extends NLS {
private static final String BUNDLE_NAME = "org.eclipse.dd.dsf.debug.ui.viewmodel.register.messages"; //$NON-NLS-1$
public static String RegisterColumnPresentation_description;
public static String RegisterColumnPresentation_name;
public static String RegisterColumnPresentation_value;
static {
// initialize resource bundle
NLS.initializeMessages(BUNDLE_NAME, MessagesForRegisterVM.class);
}
private MessagesForRegisterVM() {
}
}

View file

@ -0,0 +1,72 @@
/*******************************************************************************
* 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.register;
import org.eclipse.dd.dsf.debug.ui.DsfDebugUIPlugin;
import org.eclipse.debug.internal.ui.viewers.provisional.IColumnPresentation;
import org.eclipse.debug.internal.ui.viewers.provisional.IPresentationContext;
import org.eclipse.jface.resource.ImageDescriptor;
/**
*
*/
@SuppressWarnings("restriction")
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() {}
// @see org.eclipse.debug.internal.ui.viewers.provisional.IColumnPresentation#getAvailableColumns()
public String[] getAvailableColumns() {
return new String[] { COL_NAME, COL_VALUE, COL_DESCRIPTION };
}
// @see org.eclipse.debug.internal.ui.viewers.provisional.IColumnPresentation#getHeader(java.lang.String)
public String getHeader(String id) {
if (COL_NAME.equals(id)) {
return MessagesForRegisterVM.RegisterColumnPresentation_name;
} else if (COL_VALUE.equals(id)) {
return MessagesForRegisterVM.RegisterColumnPresentation_value;
} else if (COL_DESCRIPTION.equals(id)) {
return MessagesForRegisterVM.RegisterColumnPresentation_description;
}
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[] { COL_NAME, COL_VALUE };
}
// @see org.eclipse.debug.internal.ui.viewers.provisional.IColumnPresentation#isOptional()
public boolean isOptional() {
return true;
}
}

View file

@ -8,24 +8,26 @@
* Contributors:
* Wind River Systems - initial API and implementation
*******************************************************************************/
package org.eclipse.dd.dsf.debug.ui.viewmodel;
package org.eclipse.dd.dsf.debug.ui.viewmodel.register;
import org.eclipse.dd.dsf.concurrent.Done;
import org.eclipse.dd.dsf.concurrent.GetDataDone;
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.IRegisters.IRegisterGroupDMContext;
import org.eclipse.dd.dsf.debug.service.IRegisters.IRegisterGroupData;
import org.eclipse.dd.dsf.debug.service.IRunControl.IExecutionDMContext;
import org.eclipse.dd.dsf.service.DsfSession;
import org.eclipse.dd.dsf.service.IDsfService;
import org.eclipse.dd.dsf.ui.viewmodel.DMContextVMLayoutNode;
import org.eclipse.dd.dsf.ui.viewmodel.IVMContext;
import org.eclipse.dd.dsf.ui.viewmodel.VMDelta;
import org.eclipse.debug.internal.ui.viewers.provisional.ILabelRequestMonitor;
import org.eclipse.jface.resource.ImageDescriptor;
import org.eclipse.swt.graphics.FontData;
import org.eclipse.swt.graphics.RGB;
@SuppressWarnings("restriction")
public class RegisterGroupLayoutNode extends DMContextVMLayoutNode {
public class RegisterGroupLayoutNode extends DMContextVMLayoutNode<IRegisterGroupData> {
public RegisterGroupLayoutNode(DsfSession session) {
super(session, IRegisters.IRegisterGroupDMContext.class);
@ -43,7 +45,7 @@ public class RegisterGroupLayoutNode extends DMContextVMLayoutNode {
getServicesTracker().getService(IRegisters.class).getRegisterGroups(
execDmc, null,
new GetDataDone<IRegisterGroupDMContext[]>() { public void run() {
if (propagateError(getExecutor(), done, "Failed to retrieve register groups")) return;
if (propagateError(getExecutor(), done, "Failed to retrieve register groups")) return; //$NON-NLS-1$
done.setData(getData().length != 0);
getExecutor().execute(done);
}});
@ -61,43 +63,31 @@ public class RegisterGroupLayoutNode extends DMContextVMLayoutNode {
getServicesTracker().getService(IRegisters.class).getRegisterGroups(
execDmc, null,
new GetDataDone<IRegisterGroupDMContext[]>() { public void run() {
if (propagateError(getExecutor(), done, "Failed to retrieve register groups")) return;
if (propagateError(getExecutor(), done, "Failed to retrieve register groups")) return; //$NON-NLS-1$
done.setData(dmcs2vmcs(parentVmc, getData()));
getExecutor().execute(done);
}});
}
public void retrieveLabel( final IVMContext vmc , final ILabelRequestMonitor result ) {
if (getServicesTracker().getService(IRegisters.class) == null) {
result.done();
return;
}
final IRegisterGroupDMContext registerGroupDmc = (IRegisterGroupDMContext) ( (DMContextVMContext) vmc ).getDMC() ;
getServicesTracker().getService( IRegisters.class ).getModelData(
registerGroupDmc,
new GetDataDone<IRegisterGroupData>() {
public void run() {
if (!getStatus().isOK()) {
// Some error conditions are expected.
assert getStatus().getCode() == IDsfService.INVALID_STATE || getStatus().getCode() == IDsfService.INVALID_HANDLE : getStatus().toString();
result.setLabels( new String[] { "...", "...", "..." } ) ;
} else {
result.setLabels(new String[] { getData().getName(), "", getData().getDescription() }); //$NON-NLS-1$
}
result.done();
return;
}
}
) ;
@Override
protected void fillColumnLabel(IDMContext<IRegisterGroupData> dmContext, IRegisterGroupData dmData,
String columnId, int idx, String[] text, ImageDescriptor[] image,
FontData[] fontData, RGB[] foreground, RGB[] background)
{
if (RegisterColumnPresentation.COL_NAME.equals(columnId)) {
text[idx] = dmData.getName();
} else if (RegisterColumnPresentation.COL_VALUE.equals(columnId)) {
text[idx] = ""; //$NON-NLS-1$
} else if (RegisterColumnPresentation.COL_DESCRIPTION.equals(columnId)) {
text[idx] = dmData.getDescription();
}
}
public boolean hasDeltaFlagsForDMEvent(IDMEvent e) {
public boolean hasDeltaFlagsForDMEvent(IDMEvent<?> e) {
return super.hasDeltaFlagsForDMEvent(e);
}
public void buildDeltaForDMEvent(final IDMEvent e, final VMDelta parent, final Done done) {
public void buildDeltaForDMEvent(final IDMEvent<?> e, final VMDelta parent, final Done done) {
super.buildDeltaForDMEvent(e, parent, done);
}
}

View file

@ -8,7 +8,7 @@
* Contributors:
* Wind River Systems - initial API and implementation
*******************************************************************************/
package org.eclipse.dd.dsf.debug.ui.viewmodel;
package org.eclipse.dd.dsf.debug.ui.viewmodel.register;
import org.eclipse.dd.dsf.concurrent.Done;
import org.eclipse.dd.dsf.concurrent.GetDataDone;
@ -27,7 +27,7 @@ import org.eclipse.debug.internal.ui.viewers.provisional.ILabelRequestMonitor;
import org.eclipse.debug.internal.ui.viewers.provisional.IModelDelta;
@SuppressWarnings("restriction")
public class RegisterLayoutNode extends DMContextVMLayoutNode {
public class RegisterLayoutNode extends DMContextVMLayoutNode<IRegisterDMData> {
public IVMContext[] fCachedRegisterVMCs;
@ -48,7 +48,7 @@ public class RegisterLayoutNode extends DMContextVMLayoutNode {
registerGroupDmc,
new GetDataDone<IRegisterDMContext[]>() {
public void run() {
if (propagateError(getExecutor(), done, "Failed to retrieve registers")) return;
if (propagateError(getExecutor(), done, "Failed to retrieve registers")) return; //$NON-NLS-1$
done.setData(getData().length != 0);
getExecutor().execute(done);
}
@ -66,13 +66,13 @@ public class RegisterLayoutNode extends DMContextVMLayoutNode {
getServicesTracker().getService( IRegisters.class ).getRegisters(
execDmc,
new GetDataDone<IRegisterDMContext[]>() { public void run() {
if (propagateError(getExecutor(), done, "Failed to retrieve registers")) return;
if (propagateError(getExecutor(), done, "Failed to retrieve registers")) return; //$NON-NLS-1$
done.setData( dmcs2vmcs( parentVmc, getData()) );
getExecutor().execute(done);
}});
}
public void retrieveLabel( final IVMContext vmc , final ILabelRequestMonitor result ) {
public void retrieveLabel(final IVMContext vmc , final ILabelRequestMonitor result, String[] columns) {
if ( getServicesTracker().getService( IRegisters.class ) == null ) {
result.done();
@ -88,11 +88,11 @@ public class RegisterLayoutNode extends DMContextVMLayoutNode {
if ( !getStatus().isOK() ) {
assert getStatus().getCode() == IDsfService.INVALID_STATE || getStatus().getCode() == IDsfService.INVALID_HANDLE : getStatus().toString();
// Some error conditions are expected.
result.setLabels( new String[] { "...", "...", "..." } ) ;
result.setLabels( new String[] { "...", "...", "..." } ) ; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
} else {
String size = getData().getDescription();
String value = getData().getHexValue();
if ("".equals(size)) {
if ("".equals(size)) { //$NON-NLS-1$
if ( value.contains( "uint64" ) ) { //$NON-NLS-1$
size = "64 bit register" ; //$NON-NLS-1$
} else if ( value.contains( "v4_float" ) ) { //$NON-NLS-1$
@ -110,17 +110,19 @@ public class RegisterLayoutNode extends DMContextVMLayoutNode {
) ;
}
public boolean hasDeltaFlagsForDMEvent( IDMEvent e ) {
public boolean hasDeltaFlagsForDMEvent( IDMEvent<?> e ) {
return (e instanceof IRunControl.ISuspendedDMEvent) || super.hasDeltaFlagsForDMEvent(e) ;
}
public void buildDeltaForDMEvent( final IDMEvent e, final VMDelta parent, final Done done ) {
public void buildDeltaForDMEvent( final IDMEvent<?> e, final VMDelta parent, final Done done ) {
if (e instanceof IRunControl.ISuspendedDMEvent) {
// Create a delta that the whole register group has changed.
parent.addFlags(IModelDelta.CONTENT);
}
if (e instanceof IRegisters.IRegisterChangedDMEvent) {
parent.addNode(new DMContextVMContext(parent.getVMC(), e.getDMContext()), IModelDelta.STATE);
parent.addNode(
new DMContextVMContext(parent.getVMC(), ((IRegisters.IRegisterChangedDMEvent)e).getDMContext()),
IModelDelta.STATE);
}
super.buildDeltaForDMEvent(e, parent, done);

View file

@ -0,0 +1,46 @@
/*******************************************************************************
* 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.register;
import org.eclipse.dd.dsf.debug.ui.viewmodel.DebugViewSelectionRootLayoutNode;
import org.eclipse.dd.dsf.service.DsfSession;
import org.eclipse.dd.dsf.ui.viewmodel.IVMLayoutNode;
import org.eclipse.dd.dsf.ui.viewmodel.IVMRootLayoutNode;
import org.eclipse.dd.dsf.ui.viewmodel.VMProvider;
import org.eclipse.debug.internal.ui.viewers.provisional.IColumnPresentation;
import org.eclipse.debug.internal.ui.viewers.provisional.IPresentationContext;
/**
*
*/
@SuppressWarnings("restriction")
public class RegisterVMProvider extends VMProvider {
public RegisterVMProvider(DsfSession session, IPresentationContext context) {
super(session, null);
IVMRootLayoutNode debugViewSelection = new DebugViewSelectionRootLayoutNode(
getSession().getExecutor(), context.getPart().getSite().getWorkbenchWindow() );
IVMLayoutNode registerGroupNode = new RegisterGroupLayoutNode(getSession());
debugViewSelection.setChildNodes(new IVMLayoutNode[] { registerGroupNode });
IVMLayoutNode registerNode = new RegisterLayoutNode(getSession());
registerGroupNode.setChildNodes(new IVMLayoutNode[] { registerNode });
setRootLayoutNode(debugViewSelection);
}
@Override
public IColumnPresentation createColumnPresentation(Object element) {
return new RegisterColumnPresentation();
}
@Override
public String getColumnPresentationId(Object element) {
return RegisterColumnPresentation.ID;
}
}

View file

@ -0,0 +1,3 @@
RegisterColumnPresentation_name=Name
RegisterColumnPresentation_value=Value
RegisterColumnPresentation_description=Description

View file

@ -10,6 +10,7 @@
*******************************************************************************/
package org.eclipse.dd.dsf.ui.viewmodel;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.RejectedExecutionException;
@ -25,6 +26,8 @@ import org.eclipse.dd.dsf.ui.DsfUIPlugin;
import org.eclipse.debug.internal.ui.viewers.provisional.IAsynchronousContentAdapter;
import org.eclipse.debug.internal.ui.viewers.provisional.IAsynchronousLabelAdapter;
import org.eclipse.debug.internal.ui.viewers.provisional.IChildrenRequestMonitor;
import org.eclipse.debug.internal.ui.viewers.provisional.IColumnPresentation;
import org.eclipse.debug.internal.ui.viewers.provisional.IColumnPresentationFactoryAdapter;
import org.eclipse.debug.internal.ui.viewers.provisional.IContainerRequestMonitor;
import org.eclipse.debug.internal.ui.viewers.provisional.ILabelRequestMonitor;
import org.eclipse.debug.internal.ui.viewers.provisional.IModelProxy;
@ -39,37 +42,46 @@ import org.eclipse.debug.internal.ui.viewers.provisional.IPresentationContext;
abstract public class AbstractVMAdapter
implements IAsynchronousLabelAdapter,
IAsynchronousContentAdapter,
IModelProxyFactoryAdapter
IModelProxyFactoryAdapter,
IColumnPresentationFactoryAdapter
{
private final DsfSession fSession;
@ConfinedToDsfExecutor("getSession().getExecutor()")
private Map<IPresentationContext, VMProvider> fViewModelProviders =
new HashMap<IPresentationContext, VMProvider>();
private final Map<IPresentationContext, VMProvider> fViewModelProviders =
Collections.synchronizedMap( new HashMap<IPresentationContext, VMProvider>() );
/**
* Constructor for the View Model session. It is tempting to have the
* adapter register itself here with the session as the model adapter, but
* that would mean that the adapter might get accessed on another thread
* even before the deriving class is fully constructed. So it it better
* to have the owner of this object register it with the session.
* @param session
*/
public AbstractVMAdapter(DsfSession session) {
fSession = session;
// regieterModelAdapter() is thread safe, so we're OK calling it from here.
fSession.registerModelAdapter(IAsynchronousLabelAdapter.class, this);
fSession.registerModelAdapter(IAsynchronousContentAdapter.class, this);
fSession.registerModelAdapter(IModelProxyFactoryAdapter.class, this);
}
@ConfinedToDsfExecutor("getSession().getExecutor()")
@ThreadSafe
abstract protected VMProvider createViewModelProvider(IPresentationContext context);
protected DsfSession getSession() { return fSession; }
@ConfinedToDsfExecutor("getSession().getExecutor()")
@ThreadSafe
private VMProvider getViewModelProvider(IPresentationContext context) {
VMProvider provider = fViewModelProviders.get(context);
if (provider == null) {
provider = createViewModelProvider(context);
if (provider != null) {
fViewModelProviders.put(context, provider);
assert DsfSession.isSessionActive(getSession().getId());
synchronized(fViewModelProviders) {
VMProvider provider = fViewModelProviders.get(context);
if (provider == null) {
provider = createViewModelProvider(context);
if (provider != null) {
fViewModelProviders.put(context, provider);
}
}
return provider;
}
return provider;
}
@ConfinedToDsfExecutor("getSession().getExecutor()")
@ -80,12 +92,8 @@ abstract public class AbstractVMAdapter
public void dispose() {
assert getSession().getExecutor().isInExecutorThread();
fSession.unregisterModelAdapter(IAsynchronousLabelAdapter.class);
fSession.unregisterModelAdapter(IAsynchronousContentAdapter.class);
fSession.unregisterModelAdapter(IModelProxyFactoryAdapter.class);
for (VMProvider provider : fViewModelProviders.values()) {
provider.sessionDispose();
provider.dispose();
}
fViewModelProviders.clear();
}
@ -101,7 +109,7 @@ abstract public class AbstractVMAdapter
result.setStatus(new Status(IStatus.ERROR, DsfUIPlugin.PLUGIN_ID, IDsfService.INTERNAL_ERROR, "No model provider for object: " + object.toString(), null)); //$NON-NLS-1$
result.done();
}
provider.retrieveLabel(object, result);
provider.retrieveLabel(object, result, context.getColumns());
}
@Override
public String toString() { return "Switch to dispatch thread to execute retrieveLabel()"; } //$NON-NLS-1$
@ -161,9 +169,28 @@ abstract public class AbstractVMAdapter
* create a proxy for the root element of the tree.
*/
VMProvider provider = getViewModelProvider(context);
if (provider != null && element.equals(provider.getRootLayoutNode().getRootVMC().getInputObject())) {
if (provider != null &&
provider.getRootLayoutNode() != null &&
element.equals(provider.getRootLayoutNode().getRootVMC().getInputObject()))
{
return provider.getModelProxy();
}
return null;
}
public String getColumnPresentationId(IPresentationContext context, Object element) {
VMProvider provider = getViewModelProvider(context);
if (provider != null) {
return provider.getColumnPresentationId(element);
}
return null;
}
public IColumnPresentation createColumnPresentation(IPresentationContext context, Object element) {
VMProvider provider = getViewModelProvider(context);
if (provider != null) {
return provider.createColumnPresentation(element);
}
return null;
}
}

View file

@ -51,9 +51,9 @@ abstract public class AbstractVMLayoutNode implements IVMLayoutNode {
return fChildNodes;
}
public void sessionDispose() {
public void dispose() {
for (IVMLayoutNode childNode : getChildLayoutNodes()) {
childNode.sessionDispose();
childNode.dispose();
}
}
@ -122,7 +122,7 @@ abstract public class AbstractVMLayoutNode implements IVMLayoutNode {
}
});
}
/**
* Convenience method that returns the child layout nodes which return
* <code>true</code> to the <code>hasDeltaFlags()</code> test for the given
@ -165,5 +165,4 @@ abstract public class AbstractVMLayoutNode implements IVMLayoutNode {
result.done();
}
}

View file

@ -88,7 +88,7 @@ abstract public class AbstractVMRootLayoutNode extends AbstractVMLayoutNode impl
* There is no use case for a root node implementing this method, but its
* easier to just impelemnt it for sake of uniformity of model.
*/
public void retrieveLabel(IVMContext vmc, ILabelRequestMonitor result) {
public void retrieveLabel(IVMContext vmc, ILabelRequestMonitor result, String[] columns) {
result.done();
}

View file

@ -10,17 +10,29 @@
*******************************************************************************/
package org.eclipse.dd.dsf.ui.viewmodel;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.dd.dsf.concurrent.Done;
import org.eclipse.dd.dsf.concurrent.DoneCollector;
import org.eclipse.dd.dsf.concurrent.GetDataDone;
import org.eclipse.dd.dsf.concurrent.Immutable;
import org.eclipse.dd.dsf.datamodel.DMContexts;
import org.eclipse.dd.dsf.datamodel.IDMContext;
import org.eclipse.dd.dsf.datamodel.IDMData;
import org.eclipse.dd.dsf.datamodel.IDMEvent;
import org.eclipse.dd.dsf.datamodel.IDMService;
import org.eclipse.dd.dsf.service.DsfServicesTracker;
import org.eclipse.dd.dsf.service.DsfSession;
import org.eclipse.dd.dsf.service.IDsfService;
import org.eclipse.dd.dsf.ui.DsfUIPlugin;
import org.eclipse.dd.dsf.ui.viewmodel.IVMRootLayoutNode.IRootVMC;
import org.eclipse.debug.internal.ui.viewers.provisional.IAsynchronousLabelAdapter;
import org.eclipse.debug.internal.ui.viewers.provisional.IColumnPresentationFactoryAdapter;
import org.eclipse.debug.internal.ui.viewers.provisional.ILabelRequestMonitor;
import org.eclipse.debug.internal.ui.viewers.provisional.IModelDelta;
import org.eclipse.jface.resource.ImageDescriptor;
import org.eclipse.swt.graphics.FontData;
import org.eclipse.swt.graphics.RGB;
/**
@ -30,7 +42,7 @@ import org.eclipse.debug.internal.ui.viewers.provisional.IModelDelta;
* are of the same class type.
*/
@SuppressWarnings("restriction")
abstract public class DMContextVMLayoutNode extends AbstractVMLayoutNode {
abstract public class DMContextVMLayoutNode<V extends IDMData> extends AbstractVMLayoutNode {
/**
* IVMContext implementation used for this schema node.
@ -38,25 +50,33 @@ abstract public class DMContextVMLayoutNode extends AbstractVMLayoutNode {
@Immutable
public class DMContextVMContext implements IVMContext {
private final IVMContext fParent;
private final IDMContext<?> fDmc;
private final IDMContext<V> fDmc;
public DMContextVMContext(IVMContext parent, IDMContext<?> dmc) {
public DMContextVMContext(IVMContext parent, IDMContext<V> dmc) {
fParent = parent;
fDmc = dmc;
}
public IDMContext<?> getDMC() { return fDmc; }
public IDMContext<V> getDMC() { return fDmc; }
public IVMContext getParent() { return fParent; }
public IVMLayoutNode getLayoutNode() { return DMContextVMLayoutNode.this; }
/**
* The IAdaptable implementation. If the adapter is the DM context,
* return the context, otherwise delegate to IDMContext.getAdapter().
*/
@SuppressWarnings("unchecked")
public Object getAdapter(Class adapter) {
return fDmc.getAdapter(adapter);
if (adapter.isInstance(fDmc)) {
return fDmc;
} else {
return fDmc.getAdapter(adapter);
}
}
public boolean equals(Object other) {
if (!(other instanceof DMContextVMContext)) return false;
DMContextVMContext otherVmc = (DMContextVMContext)other;
if (!(other instanceof DMContextVMLayoutNode<?>.DMContextVMContext)) return false;
DMContextVMLayoutNode<?>.DMContextVMContext otherVmc = (DMContextVMLayoutNode<?>.DMContextVMContext)other;
return DMContextVMLayoutNode.this.equals(otherVmc.getLayoutNode()) &&
fParent.equals(otherVmc.fParent) &&
fDmc.equals(otherVmc.fDmc);
@ -75,8 +95,13 @@ abstract public class DMContextVMLayoutNode extends AbstractVMLayoutNode {
private DsfServicesTracker fServices;
/** Class type that the elements of this schema node are based on. */
private Class<? extends IDMContext<?>> fDMCClassType;
/**
* Concrete class type that the elements of this schema node are based on.
* Even though the data model type is a parameter the DMContextVMLayoutNode,
* this type is erased at runtime, so a concrete class typs of the DMC
* is needed for instanceof chacks.
*/
private Class<? extends IDMContext<V>> fDMCClassType;
/**
* Constructor initializes instance data, except for the child nodes.
@ -85,14 +110,12 @@ abstract public class DMContextVMLayoutNode extends AbstractVMLayoutNode {
* @param dmcClassType
* @see #setChildNodes(IVMLayoutNode[])
*/
public DMContextVMLayoutNode(DsfSession session, Class<? extends IDMContext<?>> dmcClassType) {
public DMContextVMLayoutNode(DsfSession session, Class<? extends IDMContext<V>> dmcClassType) {
super(session.getExecutor());
fServices = new DsfServicesTracker(DsfUIPlugin.getBundleContext(), session.getId());
fDMCClassType = dmcClassType;
}
/**
* Returns the services tracker for sub-class use.
*/
@ -100,6 +123,111 @@ abstract public class DMContextVMLayoutNode extends AbstractVMLayoutNode {
return fServices;
}
/**
* The default implementation of the retrieve label method. It acquires
* the service, using parameters in the DMC, then it fetches the model
* data from the service, and then it calls the protected method
* fillColumnLabel() for each column. The deriving classes should override
* this method if a different method of computing the label is needed.
*
* @see #fillColumnLabel(IDMData, String, int, String[], ImageDescriptor[], FontData[], RGB[], RGB[])
*/
@SuppressWarnings("unchecked")
public void retrieveLabel(IVMContext vmc, final ILabelRequestMonitor result, final String[] columns) {
/*
* Extract the DMContext from the VMContext, see DMContextVMContext.getAdapter().
* Since the VMContext is supplied by this node, the DMContext should never be null.
* Note: had to suppress type cast warnings here, because getAdapter() does not support
* generics, and even if it did, I'm not sure it would help.
*/
final IDMContext<V> dmc = (IDMContext<V>)(vmc).getAdapter(IDMContext.class);
if (dmc == null) {
assert false;
result.setStatus(new Status(IStatus.ERROR, DsfUIPlugin.PLUGIN_ID, IDsfService.INTERNAL_ERROR, "Invalid VMC type", null)); //$NON-NLS-1$
result.done();
return;
}
/*
* Get the instance of the service using the service filter in the DMContext
* If null it could mean that the service already shut down, and the view
* is holding stale elements which will be cleaned up shortly.
*/
IDMService dmService = (IDMService)getServicesTracker().getService(null, dmc.getServiceFilter());
if (dmService == null) {
handleFailedRetrieveLabel(result);
return;
}
dmService.getModelData(
dmc,
new GetDataDone<V>() {
public void run() {
/*
* Check that the request was evaluated and data is still
* valid. The request could fail if the state of the
* service changed during the request, but the view model
* has not been updated yet.
*/
if (!getStatus().isOK() || !getData().isValid()) {
assert getStatus().isOK() ||
getStatus().getCode() != IDsfService.INTERNAL_ERROR ||
getStatus().getCode() != IDsfService.NOT_SUPPORTED;
handleFailedRetrieveLabel(result);
return;
}
/*
* If columns are configured, call the protected methods to
* fill in column values.
*/
String[] localColumns = columns;
if (localColumns == null) localColumns = new String[] { null };
String[] text = new String[localColumns.length];
ImageDescriptor[] image = new ImageDescriptor[localColumns.length];
FontData[] fontData = new FontData[localColumns.length];
RGB[] foreground = new RGB[localColumns.length];
RGB[] background = new RGB[localColumns.length];
for (int i = 0; i < localColumns.length; i++) {
fillColumnLabel(dmc, getData(), localColumns[i], i, text, image, fontData, foreground, background);
}
result.setLabels(text);
result.setImageDescriptors(image);
result.setFontDatas(fontData);
result.setBackgrounds(background);
result.setForegrounds(foreground);
result.done();
}
});
}
/**
* Fills in label information for given column. This method is intended to
* be overriden by deriving classes, to supply label information specific
* to the node. <br>
* The implementation should fill in the correct value in each array at the
* given index.
* @param dmContext Data Model Context object for which the label is generated.
* @param dmData Data Model Data object retrieved from the model service.
* for the DM Context supplied to the retrieveLabel() call.
* @param columnId Name of the column to fill in, null if no columns specified.
* @param idx Index to fill in in the label arrays.
* @param text
* @param image
* @param fontData
* @param foreground
* @param background
*
* @see IAsynchronousLabelAdapter
* @see IColumnPresentationFactoryAdapter
*/
protected void fillColumnLabel(IDMContext<V> dmContext, V dmData, String columnId, int idx, String[] text,
ImageDescriptor[] image, FontData[] fontData, RGB[] foreground, RGB[] background )
{
text[idx] = ""; //$NON-NLS-1$
}
@Override
public boolean hasDeltaFlags(Object e) {
if (e instanceof IDMEvent) {
@ -139,7 +267,7 @@ abstract public class DMContextVMLayoutNode extends AbstractVMLayoutNode {
* behavior and generate a IModelDelta for every element in this schema
* node.
*/
IDMContext<?> dmc = DMContexts.getAncestorOfType(e.getDMContext(), fDMCClassType);
IDMContext<V> dmc = DMContexts.getAncestorOfType(e.getDMContext(), fDMCClassType);
if (dmc != null) {
IVMLayoutNode[] childNodes = getChildNodesWithDeltas(e);
if (childNodes.length == 0) {
@ -180,7 +308,7 @@ abstract public class DMContextVMLayoutNode extends AbstractVMLayoutNode {
* @param dmcs Array of DMC objects to build return array on.
* @return Array of IVMContext objects.
*/
protected IVMContext[] dmcs2vmcs(IVMContext parent, IDMContext<?>[] dmcs) {
protected IVMContext[] dmcs2vmcs(IVMContext parent, IDMContext<V>[] dmcs) {
IVMContext[] vmContexts = new IVMContext[dmcs.length];
for (int i = 0; i < dmcs.length; i++) {
vmContexts[i] = new DMContextVMContext(parent, dmcs[i]);
@ -216,8 +344,8 @@ abstract public class DMContextVMLayoutNode extends AbstractVMLayoutNode {
return null;
}
public void sessionDispose() {
public void dispose() {
fServices.dispose();
super.sessionDispose();
super.dispose();
}
}

View file

@ -15,6 +15,7 @@ import org.eclipse.dd.dsf.concurrent.Done;
import org.eclipse.dd.dsf.concurrent.GetDataDone;
import org.eclipse.debug.internal.ui.viewers.provisional.ILabelRequestMonitor;
import org.eclipse.debug.internal.ui.viewers.provisional.IModelDelta;
import org.eclipse.debug.internal.ui.viewers.provisional.IPresentationContext;
/**
* View model layout nodes are combined together into a tree, to collectively
@ -52,8 +53,10 @@ public interface IVMLayoutNode {
* Retrieves the label for the given element.
* @param vmc Element for which to retrieve label information.
* @param result Monitor which accepts the data.
* @param columns Currently configured columns in view.
* @see IPresentationContext
*/
public void retrieveLabel(IVMContext vmc, ILabelRequestMonitor result);
public void retrieveLabel(IVMContext vmc, ILabelRequestMonitor result, String[] columns);
/**
* Configures the child layout nodes for this node.
@ -89,5 +92,5 @@ public interface IVMLayoutNode {
/**
* Disposes the resources held by this node.
*/
public void sessionDispose();
public void dispose();
}

View file

@ -27,11 +27,13 @@ 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.debug.internal.ui.viewers.provisional.IChildrenRequestMonitor;
import org.eclipse.debug.internal.ui.viewers.provisional.IColumnEditorFactoryAdapter;
import org.eclipse.debug.internal.ui.viewers.provisional.IColumnPresentation;
import org.eclipse.debug.internal.ui.viewers.provisional.IContainerRequestMonitor;
import org.eclipse.debug.internal.ui.viewers.provisional.ILabelRequestMonitor;
import org.eclipse.debug.internal.ui.viewers.provisional.IModelChangedListener;
import org.eclipse.debug.internal.ui.viewers.provisional.IModelDelta;
import org.eclipse.debug.internal.ui.viewers.provisional.IModelProxy;
import org.eclipse.debug.internal.ui.viewers.provisional.IPresentationContext;
/**
* View model provider implements the asynchronous view model functionality for
@ -52,83 +54,48 @@ import org.eclipse.debug.internal.ui.viewers.provisional.IModelProxy;
@SuppressWarnings("restriction")
public class VMProvider
{
@ThreadSafe
public 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.
*/
private ISchedulingRule fModelChangeRule = new ISchedulingRule() {
public boolean contains(ISchedulingRule rule) { return this == rule; }
public boolean isConflicting(ISchedulingRule rule) { return rule == this; }
};
public void installed() {
fProxyActive++;
}
public void dispose() {
fProxyActive--;
super.dispose();
}
@Override
public void removeModelChangedListener(IModelChangedListener listener) {
// TODO Auto-generated method stub
super.removeModelChangedListener(listener);
}
@Override
public void addModelChangedListener(IModelChangedListener listener) {
// TODO Auto-generated method stub
super.addModelChangedListener(listener);
}
/**
* 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$
protected IStatus run(IProgressMonitor monitor) {
fireModelChanged(delta);
return Status.OK_STATUS;
}
};
job.setPriority(Job.INTERACTIVE);
job.setRule(fModelChangeRule);
job.schedule();
}
}
private final DsfSession fSession;
private final ModelProxy fModelProxy = new ModelProxy();
/**
* It is theoretically possible for a VMProvider to be disposed before it
* has a chance to register itself as event listener. This flag is used
* to avoid removing itself as listener in such situation.
*/
private boolean fRegisteredAsEventListener = false;
/**
* The root node for this model provider. The root layout node could be
* null when first created, to allow sub-classes to prorperly configure the
* root node in the sub-class constructor.
*/
private IVMRootLayoutNode fRootLayoutNode;
/**
* Constructs the view model provider for given DSF session.
* Constructs the view model provider for given DSF session. The
* constructor is thread-safe to allow VM provider to be constructed
* synchronously when a call to getAdapter() is made on an element
* in a view.
*/
@ThreadSafe
public VMProvider(DsfSession session, IVMRootLayoutNode rootLayoutNode) {
fSession = session;
setRootLayoutNode(rootLayoutNode);
fRootLayoutNode = rootLayoutNode;
// Add ourselves as listener for DM events events.
session.addServiceEventListener(this, null);
session.getExecutor().execute(new Runnable() {
public void run() {
if (DsfSession.isSessionActive(getSession().getId())) {
getSession().addServiceEventListener(VMProvider.this, null);
fRegisteredAsEventListener = true;
}
}
});
}
/** Sets the layout nodes */
public void setRootLayoutNode(IVMRootLayoutNode rootLayoutNode) {
if (fRootLayoutNode != null) {
fRootLayoutNode.sessionDispose();
fRootLayoutNode.dispose();
}
fRootLayoutNode = rootLayoutNode;
}
@ -138,9 +105,13 @@ public class VMProvider
}
/** Called to dispose the provider. */
public void sessionDispose() {
fSession.removeServiceEventListener(this);
fRootLayoutNode.sessionDispose();
public void dispose() {
if (fRegisteredAsEventListener) {
fSession.removeServiceEventListener(this);
}
if (fRootLayoutNode != null) {
fRootLayoutNode.dispose();
}
}
protected DsfSession getSession() { return fSession; }
@ -248,6 +219,71 @@ public class VMProvider
}
}
/**
* Retrieves the label information for given object.
* The implementation converts the object into a VM-Context, then delegates
* to the context's layout node.
* Note: this method must be called on the provider's dispatch thread.
* @see IAsynchronousLabelAdapter#retrieveLabel(Object, org.eclipse.debug.internal.ui.viewers.provisional.IPresentationContext, ILabelRequestMonitor)
*/
public void retrieveLabel(Object object, ILabelRequestMonitor result, String[] columns)
{
IVMContext vmc = getVmcForObject(object);
if (vmc == null) {
result.done();
return;
}
vmc.getLayoutNode().retrieveLabel(vmc, result, columns);
}
public ModelProxy getModelProxy() {
return fModelProxy;
}
/**
* Creates the column presentation for the given object. This method is meant
* to be overriden by deriving class to provide view-specific functionality.
* The default is to return null, meaning no columns.
* <p>
* The viewer only reads the column presentation for the root/input element of
* the tree/table, so the VMProvider must be configured to own the root element
* in the view in order for this setting to be effective.
* <p>
* Note: since the IColumnEditorFactoryAdapter interface is synchronous, and since
* column info is fairly static, this method is thread-safe, and it will
* not be called on the executor thread.
*
* @see IColumnEditorFactoryAdapter#createColumnEditor(IPresentationContext, Object)
*/
@ThreadSafe
public IColumnPresentation createColumnPresentation(Object element) {
return null;
}
/**
* Returns the ID of the column presentation for the given object. This method
* is meant to be overriden by deriving class to provide view-specific
* functionality. The default is to return null, meaning no columns.
* <p>
* The viewer only reads the column presentation for the root/input element of
* the tree/table, so the VMProvider must be configured to own the root element
* in the view in order for this setting to be effective.
* <p>
* Note: since the IColumnEditorFactoryAdapter interface is synchronous, and since
* column info is fairly static, this method is thread-safe, and it will
* not be called on the executor thread.
*
* @see IColumnEditorFactoryAdapter#getColumnEditorId(IPresentationContext, Object)
*/
@ThreadSafe
public String getColumnPresentationId(Object element) {
return null;
}
/**
* Convenience method that finds the VMC corresponding to given parent
* argument given to isContainer() or retrieveChildren().
@ -293,28 +329,7 @@ public class VMProvider
}
return false;
}
/**
* Retrieves the label information for given VMC.
* Note: this method must be called on the provider's dispatch thread.
* @see IAsynchronousLabelAdapter#retrieveLabel(Object, org.eclipse.debug.internal.ui.viewers.provisional.IPresentationContext, ILabelRequestMonitor)
*/
public void retrieveLabel(Object object, final ILabelRequestMonitor result)
{
IVMContext vmc = getVmcForObject(object);
if (vmc == null) {
result.done();
return;
}
vmc.getLayoutNode().retrieveLabel(vmc, result);
}
public ModelProxy getModelProxy() {
return fModelProxy;
}
/**
* Handle "data model changed" event by generating a delta object for each
* view and passing it to the corresponding view model provider. The view
@ -337,4 +352,50 @@ public class VMProvider
});
}
}
@ThreadSafe
public 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.
*/
private ISchedulingRule fModelChangeRule = new ISchedulingRule() {
public boolean contains(ISchedulingRule rule) { return this == rule; }
public boolean isConflicting(ISchedulingRule rule) { return rule == this; }
};
public void installed() {
fProxyActive++;
}
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$
protected IStatus run(IProgressMonitor monitor) {
fireModelChanged(delta);
return Status.OK_STATUS;
}
};
job.setPriority(Job.INTERACTIVE);
job.setRule(fModelChangeRule);
job.schedule();
}
}
}

View file

@ -48,23 +48,24 @@ public class DsfServicesTracker {
private static class ServiceKey
{
String fClassString;
String fClassName;
String fFilter;
public ServiceKey(String classString, String filter) {
fClassString = classString;
public ServiceKey(Class<?> clazz, String filter) {
fClassName = clazz != null ? clazz.getName() : null;
fFilter = filter;
}
public boolean equals(Object other) {
// I guess this doesn't have to assume fFilter can be null, but oh well.
return other instanceof ServiceKey &&
((ServiceKey)other).fClassString.equals(fClassString) &&
return other instanceof ServiceKey &&
((fClassName == null && ((ServiceKey)other).fClassName == null) ||
(fClassName != null && fClassName.equals(((ServiceKey)other).fClassName))) &&
((fFilter == null && ((ServiceKey)other).fFilter == null) ||
(fFilter != null && fFilter.equals(((ServiceKey)other).fFilter)));
}
public int hashCode() {
return fClassString.hashCode() + (fFilter == null ? 0 : fFilter.hashCode());
return (fClassName == null ? 0 : fClassName.hashCode()) + (fFilter == null ? 0 : fFilter.hashCode());
}
}
@ -95,13 +96,13 @@ public class DsfServicesTracker {
*/
@SuppressWarnings("unchecked")
public ServiceReference getServiceReference(Class serviceClass, String filter) {
ServiceKey key = new ServiceKey(serviceClass.getName().intern(), filter != null ? filter : fServiceFilter);
ServiceKey key = new ServiceKey(serviceClass, filter != null ? filter : fServiceFilter);
if (fServiceReferences.containsKey(key)) {
return fServiceReferences.get(key);
}
try {
ServiceReference[] references = fBundleContext.getServiceReferences(key.fClassString, key.fFilter);
ServiceReference[] references = fBundleContext.getServiceReferences(key.fClassName, key.fFilter);
assert references == null || references.length <= 1;
if (references == null || references.length == 0) {
return null;