1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-07-24 09:25:31 +02:00

- Refactored view model implementation so that more of the common code is integrated into base classes (bug# 161981).

- Split org.eclipse.dd.dsf so that packages depending on org.eclipse.debug.core are in a separate plugin (bug# 161948).
- Refactored Data Model and View Model interfaces and classes to use a consistent naming scheme.
This commit is contained in:
Pawel Piech 2006-11-01 21:53:48 +00:00
parent 3173aac06c
commit 9ff6415403
71 changed files with 2931 additions and 881 deletions

View file

@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry kind="src" path="src"/>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/J2SE-1.5"/>
<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
<classpathentry kind="output" path="bin"/>
</classpath>

View file

@ -0,0 +1,28 @@
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>org.eclipse.dd.dsf.debug.ui</name>
<comment></comment>
<projects>
</projects>
<buildSpec>
<buildCommand>
<name>org.eclipse.jdt.core.javabuilder</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>org.eclipse.pde.ManifestBuilder</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>org.eclipse.pde.SchemaBuilder</name>
<arguments>
</arguments>
</buildCommand>
</buildSpec>
<natures>
<nature>org.eclipse.pde.PluginNature</nature>
<nature>org.eclipse.jdt.core.javanature</nature>
</natures>
</projectDescription>

View file

@ -0,0 +1,12 @@
#Wed Nov 01 13:23:23 PST 2006
eclipse.preferences.version=1
org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.5
org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
org.eclipse.jdt.core.compiler.compliance=1.5
org.eclipse.jdt.core.compiler.debug.lineNumber=generate
org.eclipse.jdt.core.compiler.debug.localVariable=generate
org.eclipse.jdt.core.compiler.debug.sourceFile=generate
org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
org.eclipse.jdt.core.compiler.source=1.5

View file

@ -0,0 +1,22 @@
Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: %pluginName
Bundle-Vendor: %providerName
Bundle-SymbolicName: org.eclipse.dd.dsf.debug.ui
Bundle-Version: 1.0.0
Bundle-Activator: org.eclipse.dd.dsf.debug.ui.DsfDebugUIPlugin
Bundle-Localization: plugin
Require-Bundle: org.eclipse.ui,
org.eclipse.core.runtime,
org.eclipse.core.variables,
org.eclipse.debug.core,
org.eclipse.debug.ui,
org.eclipse.ui.ide,
org.eclipse.dd.dsf,
org.eclipse.dd.dsf.ui,
org.eclipse.dd.dsf.debug,
org.eclipse.dd.dsf.mi.core
Eclipse-LazyStart: true
Export-Package:
org.eclipse.dd.dsf.debug.ui.viewmodel
Bundle-RequiredExecutionEnvironment: J2SE-1.5

View file

@ -0,0 +1,4 @@
source.. = src/
output.. = bin/
bin.includes = META-INF/,\
.

View file

@ -0,0 +1,13 @@
###############################################################################
# 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
###############################################################################
pluginName=DSDP/DD Debugger Services Framework (DSF) Debug UI
providerName=Eclipse.org

View file

@ -0,0 +1,61 @@
package org.eclipse.dd.dsf.debug.ui;
import org.eclipse.jface.resource.ImageDescriptor;
import org.eclipse.ui.plugin.AbstractUIPlugin;
import org.osgi.framework.BundleContext;
/**
* The activator class controls the plug-in life cycle
*/
public class DsfDebugUIPlugin extends AbstractUIPlugin {
// The plug-in ID
public static final String PLUGIN_ID = "org.eclipse.dd.dsf.debug.ui";
// The shared instance
private static DsfDebugUIPlugin plugin;
/**
* The constructor
*/
public DsfDebugUIPlugin() {
}
/*
* (non-Javadoc)
* @see org.eclipse.ui.plugin.AbstractUIPlugin#start(org.osgi.framework.BundleContext)
*/
public void start(BundleContext context) throws Exception {
super.start(context);
plugin = this;
}
/*
* (non-Javadoc)
* @see org.eclipse.ui.plugin.AbstractUIPlugin#stop(org.osgi.framework.BundleContext)
*/
public void stop(BundleContext context) throws Exception {
plugin = null;
super.stop(context);
}
/**
* Returns the shared instance
*
* @return the shared instance
*/
public static DsfDebugUIPlugin getDefault() {
return plugin;
}
/**
* Returns an image descriptor for the image file at the given
* plug-in relative path
*
* @param path the path
* @return the image descriptor
*/
public static ImageDescriptor getImageDescriptor(String path) {
return imageDescriptorFromPlugin(PLUGIN_ID, path);
}
}

View file

@ -0,0 +1,70 @@
/*******************************************************************************
* 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.concurrent.DsfRunnable;
import org.eclipse.dd.dsf.concurrent.GetDataDone;
import org.eclipse.dd.dsf.service.DsfSession;
import org.eclipse.dd.dsf.ui.viewmodel.IVMRootLayoutNode;
import org.eclipse.dd.dsf.ui.viewmodel.VMProvider;
import org.eclipse.debug.core.DebugEvent;
import org.eclipse.debug.core.DebugPlugin;
import org.eclipse.debug.core.IDebugEventSetListener;
import org.eclipse.debug.internal.ui.viewers.provisional.IModelDelta;
/**
*
*/
@SuppressWarnings("restriction")
public class DebugViewModelProvider extends VMProvider
implements IDebugEventSetListener
{
public DebugViewModelProvider(DsfSession session, IVMRootLayoutNode rootLayoutNode) {
super(session, rootLayoutNode);
DebugPlugin.getDefault().addDebugEventListener(this);
}
public void handleDebugEvents(final DebugEvent[] events) {
getSession().getExecutor().execute(new DsfRunnable() {
public void run() {
for (DebugEvent event : events) {
handleDebugEvent(event);
}
}
});
}
private void handleDebugEvent(DebugEvent event) {
/*
* Just like with DMC events, go through all the layout nodes and
* collect delta information for the received event.
*/
if (getRootLayoutNode().hasDeltaFlags(event)) {
getRootLayoutNode().createDelta(event, new GetDataDone<IModelDelta>() {
public void run() {
if (getStatus().isOK()) {
getModelProxy().fireModelChangedNonDispatch(getData());
}
}
});
}
}
@Override
public void sessionDispose() {
DebugPlugin.getDefault().removeDebugEventListener(this);
super.sessionDispose();
}
}

View file

@ -0,0 +1,116 @@
/*******************************************************************************
* 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.concurrent.DsfExecutor;
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.ui.viewmodel.AbstractVMRootLayoutNode;
import org.eclipse.dd.dsf.ui.viewmodel.IVMRootLayoutNode;
import org.eclipse.dd.dsf.ui.viewmodel.DMContextVMLayoutNode.DMContextVMContext;
import org.eclipse.debug.internal.ui.contexts.DebugContextManager;
import org.eclipse.debug.internal.ui.contexts.provisional.IDebugContextListener;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.ui.IWorkbenchPart;
import org.eclipse.ui.IWorkbenchWindow;
/**
* This is is a standard root node which listens to the selection in Debug View.
* Views such as variables and registers base their content based on the
* selection in Debug view, and this node provides tracking of that selection.
*/
@SuppressWarnings("restriction")
public class DebugViewSelectionRootLayoutNode extends AbstractVMRootLayoutNode
implements IVMRootLayoutNode, IDebugContextListener
{
private RootVMC<Object> fRootVMC;
public DebugViewSelectionRootLayoutNode(DsfExecutor executor, IWorkbenchWindow window) {
super(executor);
DebugContextManager.getDefault().addDebugContextListener(this, window);
}
@Override
public void sessionDispose() {
DebugContextManager.getDefault().removeDebugContextListener(this);
super.sessionDispose();
}
/**
* If the input object is a DMC-VMC, and the event is a DMC event.
* Then we can filter the event to make sure that the view does not
* react to events that relate to objects outside this view.
*
* The logic is such:
* - iterate through the full hierarchy of the DMC in the event,
* - for each DMC in event, search for a DMC of the same type in the input
* event,
* - if an ancestor of that type is found, it indicates that the event
* and the input object share the same hierarchy
* - finally compare the DMContexts from the event to the DMC from the input
* object,
* - if there is a match then we know that the event relates
* to the hierarchy in view,
* - if there is no match, then we know that the event related to a
* some sibling of the input object, and no delta should be generated,
* - if none of the ancestor types matched, then the event is completely
* unrelated to the input object, and the layout nodes in the view must
* determine whether a delta is needed.
*/
@Override
public boolean hasDeltaFlags(Object event) {
/*
* TODO: This logic needs to be tested and probably enhanced.
*/
if (event instanceof IDMEvent && fRootVMC.getInputObject() instanceof DMContextVMContext) {
boolean potentialMatchFound = false;
boolean matchFound = false;
IDMContext eventDmc = ((IDMEvent)event).getDMContext();
IDMContext inputDmc = ((DMContextVMContext)fRootVMC.getInputObject()).getDMC();
for (IDMContext eventDmcAncestor : DMContexts.toList(eventDmc)) {
IDMContext inputDmcAncestor = DMContexts.getAncestorOfType(inputDmc, eventDmcAncestor.getClass());
if (inputDmcAncestor != null) {
potentialMatchFound = true;
if (inputDmcAncestor.equals(eventDmcAncestor)) {
matchFound = true;
}
}
}
if (potentialMatchFound && !matchFound) {
return false;
}
}
return super.hasDeltaFlags(event);
}
public IRootVMC getRootVMC() {
return fRootVMC;
}
public void contextActivated(ISelection selection, IWorkbenchPart part) {
if (selection instanceof IStructuredSelection) {
fRootVMC = new RootVMC<Object>( this, ((IStructuredSelection)selection).getFirstElement() );
} else {
fRootVMC = null;
}
// TODO: Do we need to generate a delta for the view? Or will Debug view
// selection change somehow cause a refresh anyway.
}
public void contextChanged(ISelection selection, IWorkbenchPart part) {
// No need to do anything. Element changes should be handled
// through standard event handlers.
}
}

View file

@ -0,0 +1,103 @@
/*******************************************************************************
* 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.concurrent.Done;
import org.eclipse.dd.dsf.concurrent.GetDataDone;
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;
@SuppressWarnings("restriction")
public class RegisterGroupLayoutNode extends DMContextVMLayoutNode {
public RegisterGroupLayoutNode(DsfSession session) {
super(session, IRegisters.IRegisterGroupDMContext.class);
}
public void hasElements( final IVMContext parentVmc , final GetDataDone<Boolean> done ) {
final IExecutionDMContext execDmc = findDmcInVmc(parentVmc, IExecutionDMContext.class);
if (execDmc == null || getServicesTracker().getService(IRegisters.class) == null) {
done.setData(Boolean.FALSE);
getExecutor().execute(done);
return;
}
getServicesTracker().getService(IRegisters.class).getRegisterGroups(
execDmc, null,
new GetDataDone<IRegisterGroupDMContext[]>() { public void run() {
if (propagateError(getExecutor(), done, "Failed to retrieve register groups")) return;
done.setData(getData().length != 0);
getExecutor().execute(done);
}});
}
public void getElements( final IVMContext parentVmc, final GetDataDone<IVMContext[]> done ) {
final IExecutionDMContext execDmc = findDmcInVmc(parentVmc, IExecutionDMContext.class) ;
if ( execDmc == null || getServicesTracker().getService( IRegisters.class ) == null ) {
done.setData(new IVMContext[0]);
getExecutor().execute( done );
return;
}
getServicesTracker().getService(IRegisters.class).getRegisterGroups(
execDmc, null,
new GetDataDone<IRegisterGroupDMContext[]>() { public void run() {
if (propagateError(getExecutor(), done, "Failed to retrieve register groups")) return;
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;
}
}
) ;
}
public boolean hasDeltaFlagsForDMEvent(IDMEvent e) {
return super.hasDeltaFlagsForDMEvent(e);
}
public void buildDeltaForDMEvent(final IDMEvent e, final VMDelta parent, final Done done) {
super.buildDeltaForDMEvent(e, parent, done);
}
}

View file

@ -0,0 +1,128 @@
/*******************************************************************************
* 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.concurrent.Done;
import org.eclipse.dd.dsf.concurrent.GetDataDone;
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.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.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.debug.internal.ui.viewers.provisional.IModelDelta;
@SuppressWarnings("restriction")
public class RegisterLayoutNode extends DMContextVMLayoutNode {
public IVMContext[] fCachedRegisterVMCs;
public RegisterLayoutNode(DsfSession session) {
super(session, IRegisters.IRegisterDMContext.class);
}
public void hasElements( final IVMContext parentVmc , final GetDataDone<Boolean> done ) {
final IRegisterGroupDMContext registerGroupDmc = findDmcInVmc(parentVmc, IRegisterGroupDMContext.class);
if (registerGroupDmc == null || getServicesTracker().getService(IRegisters.class) == null) {
done.setData(Boolean.FALSE);
getExecutor().execute(done);
return;
}
getServicesTracker().getService( IRegisters.class ).getRegisters(
registerGroupDmc,
new GetDataDone<IRegisterDMContext[]>() {
public void run() {
if (propagateError(getExecutor(), done, "Failed to retrieve registers")) return;
done.setData(getData().length != 0);
getExecutor().execute(done);
}
});
}
public void getElements( final IVMContext parentVmc , final GetDataDone<IVMContext[]> done ) {
final IRegisterGroupDMContext execDmc = findDmcInVmc(parentVmc, IRegisterGroupDMContext.class);
if (execDmc == null || getServicesTracker().getService(IRegisters.class) == null) {
getExecutor().execute(done);
return;
}
getServicesTracker().getService( IRegisters.class ).getRegisters(
execDmc,
new GetDataDone<IRegisterDMContext[]>() { public void run() {
if (propagateError(getExecutor(), done, "Failed to retrieve registers")) return;
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 IRegisterDMContext registerDmc = (IRegisterDMContext) ( (DMContextVMContext) vmc ).getDMC() ;
getServicesTracker().getService( IRegisters.class ).getModelData(
registerDmc ,
new GetDataDone<IRegisterDMData>() {
public void run() {
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[] { "...", "...", "..." } ) ;
} else {
String size = getData().getDescription();
String value = getData().getHexValue();
if ("".equals(size)) {
if ( value.contains( "uint64" ) ) { //$NON-NLS-1$
size = "64 bit register" ; //$NON-NLS-1$
} else if ( value.contains( "v4_float" ) ) { //$NON-NLS-1$
size = "128 bit register" ; //$NON-NLS-1$
}
}
result.setLabels(new String[] { getData().getName(), getData().getHexValue(), size });
}
result.done() ;
return ;
}
}
) ;
}
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 ) {
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);
}
super.buildDeltaForDMEvent(e, parent, done);
}
}

View file

@ -0,0 +1,272 @@
/*******************************************************************************
* 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.MultiStatus;
import org.eclipse.dd.dsf.concurrent.Done;
import org.eclipse.dd.dsf.concurrent.GetDataDone;
import org.eclipse.dd.dsf.datamodel.IDMEvent;
import org.eclipse.dd.dsf.debug.service.IRunControl;
import org.eclipse.dd.dsf.debug.service.IStack;
import org.eclipse.dd.dsf.debug.service.IStepQueueManager;
import org.eclipse.dd.dsf.debug.service.IRunControl.IExecutionDMContext;
import org.eclipse.dd.dsf.debug.service.IRunControl.StateChangeReason;
import org.eclipse.dd.dsf.debug.service.IStack.IFrameDMContext;
import org.eclipse.dd.dsf.debug.service.IStack.IFrameDMData;
import org.eclipse.dd.dsf.debug.ui.DsfDebugUIPlugin;
import org.eclipse.dd.dsf.service.DsfSession;
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.debug.internal.ui.viewers.provisional.IModelDelta;
import org.eclipse.debug.ui.DebugUITools;
import org.eclipse.debug.ui.IDebugUIConstants;
import org.eclipse.jface.resource.ImageDescriptor;
@SuppressWarnings("restriction")
public class StackFramesLayoutNode extends DMContextVMLayoutNode {
public IVMContext[] fCachedOldFramesVMCs;
public StackFramesLayoutNode(DsfSession session) {
super(session, IStack.IFrameDMContext.class);
}
public void hasElements(IVMContext parentVmc, final GetDataDone<Boolean> done) {
IExecutionDMContext execDmc = findDmcInVmc(parentVmc, IExecutionDMContext.class);
if (execDmc == null || getServicesTracker().getService(IStack.class) == null || getServicesTracker().getService(IRunControl.class) == null) {
done.setData(false);
getExecutor().execute(done);
return;
}
done.setData(getServicesTracker().getService(IStack.class).isStackAvailable(execDmc));
getExecutor().execute(done);
}
public void getElements(final IVMContext parentVmc, final GetDataDone<IVMContext[]> done) {
final IExecutionDMContext execDmc = findDmcInVmc(parentVmc, IExecutionDMContext.class);
if (execDmc == null || getServicesTracker().getService(IStack.class) == null || getServicesTracker().getService(IRunControl.class) == null) {
done.setData(new IVMContext[0]);
getExecutor().execute(done);
return;
}
getServicesTracker().getService(IStack.class).getFrames(
execDmc,
new GetDataDone<IFrameDMContext[]>() { public void run() {
if (!getStatus().isOK()) {
// Failed to retrieve frames. If we are stepping, we
// might still be able to retrieve just the top stack
// frame, which would still be useful in Debug View.
if (getServicesTracker().getService(IRunControl.class).isStepping(execDmc)) {
getElementsTopStackFrameOnly(parentVmc, done);
} else {
propagateError(getExecutor(), done, "Failed retrieving stack frames");
}
return;
}
// Store the VMC element array, in case we need to use it when
fCachedOldFramesVMCs = dmcs2vmcs(parentVmc, getData());
done.setData(fCachedOldFramesVMCs);
getExecutor().execute(done);
}});
}
/**
* Retrieves teh list of VMC elements for a full stack trace, but with only
* the top stack frame being retrieved from the service. The rest of the
* frames are retrieved from the cache or omitted.
* @see #getElements(IVMContext, GetDataDone)
*/
private void getElementsTopStackFrameOnly(final IVMContext parentVmc, final GetDataDone<IVMContext[]> done) {
final IExecutionDMContext execDmc = findDmcInVmc(parentVmc, IExecutionDMContext.class);
getServicesTracker().getService(IStack.class).getTopFrame(
execDmc,
new GetDataDone<IFrameDMContext>() { public void run() {
if (propagateError(getExecutor(), done, "Failed retrieving top stack frame")) return;
IVMContext topFrameVmc = new DMContextVMContext(parentVmc, getData());
// If there are old frames cached, use them and only substitute the top frame object. Otherwise, create
// an array of VMCs with just the top frame.
if (fCachedOldFramesVMCs != null && fCachedOldFramesVMCs.length >= 1) {
fCachedOldFramesVMCs[0] = topFrameVmc;
done.setData(fCachedOldFramesVMCs);
} else {
done.setData(new IVMContext[] { topFrameVmc });
}
getExecutor().execute(done);
}});
}
public void retrieveLabel(IVMContext vmc, final ILabelRequestMonitor result) {
final IExecutionDMContext execDmc = findDmcInVmc(vmc, IExecutionDMContext.class);
if (execDmc == null || getServicesTracker().getService(IStack.class) == null || getServicesTracker().getService(IRunControl.class) == null) {
result.done();
return;
}
String imageKey = null;
IRunControl rc = getServicesTracker().getService(IRunControl.class);
if (rc.isSuspended(execDmc) ||
(rc.isStepping(execDmc) && !getServicesTracker().getService(IStepQueueManager.class).isSteppingTimedOut(execDmc)))
{
imageKey = IDebugUIConstants.IMG_OBJS_STACKFRAME;
} else {
imageKey = IDebugUIConstants.IMG_OBJS_STACKFRAME_RUNNING;
}
result.setImageDescriptors(new ImageDescriptor[] { DebugUITools.getImageDescriptor(imageKey) });
IFrameDMContext frameDmc = (IFrameDMContext)((DMContextVMContext)vmc).getDMC();
getServicesTracker().getService(IStack.class).getModelData(
frameDmc,
new GetDataDone<IFrameDMData>() { public void run() {
// Check if services are still available.
if (getServicesTracker().getService(IRunControl.class) == null) {
result.done();
return;
}
if (!getStatus().isOK()) {
// 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[] { "..." });
if (!getServicesTracker().getService(IRunControl.class).isStepping(execDmc)) {
MultiStatus status = new MultiStatus(DsfDebugUIPlugin.PLUGIN_ID, 0, "Failed to retrieve stack frame label", null);
status.add(getStatus());
result.setStatus(status);
}
result.done();
return;
}
//
// Finally, if all goes well, set the label.
//
StringBuilder label = new StringBuilder();
// Add frame number (if total number of frames in known)
if (fCachedOldFramesVMCs != null) {
label.append(fCachedOldFramesVMCs.length - getData().getLevel());
}
// Add the function name
if (getData().getFunction() != null && getData().getFunction().length() != 0) {
label.append(" ");
label.append(getData().getFunction());
label.append("()");
}
// Add full file name
if (getData().getFile() != null && getData().getFile().length() != 0) {
label.append(" at ");
label.append(getData().getFile());
}
// Add line number
if (getData().getLine() >= 0) {
label.append(":");
label.append(getData().getLine());
label.append(" ");
}
// Add the address
label.append(getData().getAddress());
// Set the label to the result listener
result.setLabels(new String[] { label.toString() });
result.done();
}});
}
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 ||
e instanceof IRunControl.IResumedDMEvent ||
e instanceof IStepQueueManager.ISteppingTimedOutEvent ||
super.hasDeltaFlagsForDMEvent(e);
}
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);
return;
}
if (e instanceof IRunControl.ISuspendedDMEvent) {
IRunControl.ISuspendedDMEvent suspendedEvent = (IRunControl.ISuspendedDMEvent)e;
// Refresh the whole list of stack frames unless the target is already stepping the next command. In
// which case, the refresh will occur when the stepping sequence slows down or stops. Trying to
// refresh the whole stack trace with every step would slow down stepping too much.
if (!getServicesTracker().getService(IRunControl.class).isStepping(suspendedEvent.getDMContext())) {
parent.addFlags(IModelDelta.CONTENT);
}
// Always expand the thread node to show the stack frames.
parent.addFlags(IModelDelta.EXPAND);
// Retrieve the list of stack frames, and mark the top frame to be selected.
getElementsTopStackFrameOnly(
parent.getVMC(),
new GetDataDone<IVMContext[]>() { public void run() {
if (getStatus().isOK() && getData().length != 0) {
parent.addNode( getData()[0], IModelDelta.SELECT | IModelDelta.STATE);
// If second frame is available repaint it, so that a "..." appears. This gives a better
// impression that the frames are not up-to date.
if (getData().length >= 2) {
parent.addNode( getData()[1], IModelDelta.STATE);
}
}
// Even in case of errors, call super-class to complete building of the delta.
StackFramesLayoutNode.super.buildDeltaForDMEvent(e, parent, done);
}});
} else if (e instanceof IRunControl.IResumedDMEvent) {
IRunControl.IResumedDMEvent resumedEvent = (IRunControl.IResumedDMEvent)e;
getExecutor().execute(done);
if (resumedEvent.getReason() == StateChangeReason.STEP) {
// TODO: Refreshing the state of the top stack frame is only necessary to re-enable the step button.
// This is because platform disables the step action every time after it is invoked. Need to file
// a bug on this.
getServicesTracker().getService(IStack.class).getTopFrame(
resumedEvent.getDMContext(),
new GetDataDone<IFrameDMContext>() { public void run() {
if (getStatus().isOK()) {
parent.addNode(new DMContextVMContext(parent.getVMC(), getData()), IModelDelta.STATE);
}
StackFramesLayoutNode.super.buildDeltaForDMEvent(e, parent, done);
}});
StackFramesLayoutNode.super.buildDeltaForDMEvent(e, parent, done);
} else {
// Refresh the list of stack frames only if the run operation is not a step. Also, clear the list
// of cached frames.
parent.addFlags(IModelDelta.CONTENT);
fCachedOldFramesVMCs = null;
// Call super-class to build sub-node delta's.
super.buildDeltaForDMEvent(e, parent, done);
}
} else if (e instanceof IStepQueueManager.ISteppingTimedOutEvent) {
// Repaint the stack frame images to have the running symbol.
parent.addFlags(IModelDelta.CONTENT);
super.buildDeltaForDMEvent(e, parent, done);
} else {
// Call super-class to build sub-node delta's.
super.buildDeltaForDMEvent(e, parent, done);
}
}
}

View file

@ -0,0 +1,103 @@
/*******************************************************************************
* 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.concurrent.DoneCollector;
import org.eclipse.dd.dsf.concurrent.DsfExecutor;
import org.eclipse.dd.dsf.concurrent.GetDataDone;
import org.eclipse.dd.dsf.ui.viewmodel.AbstractVMRootLayoutNode;
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.VMDelta;
import org.eclipse.debug.core.DebugEvent;
import org.eclipse.debug.core.DebugPlugin;
import org.eclipse.debug.core.ILaunch;
import org.eclipse.debug.core.model.IDebugElement;
import org.eclipse.debug.core.model.IProcess;
import org.eclipse.debug.internal.ui.viewers.provisional.IModelDelta;
/**
* Layout node for the standard ILaunch object. This node can only be used at
* the root of a hierarchy. It does not implement the label provider
* functionality, so the default adapters should be used to retrieve the label.
*/
@SuppressWarnings("restriction")
public class StandardLaunchRootLayoutNode extends AbstractVMRootLayoutNode
implements IVMRootLayoutNode
{
final private RootVMC<ILaunch> fRootVMC;
final IVMContext[] fElements;
public StandardLaunchRootLayoutNode(DsfExecutor executor, ILaunch launch) {
super(executor);
fRootVMC = new RootVMC<ILaunch>(this, launch);
fElements = new IVMContext[] { fRootVMC };
}
@Override
public boolean hasDeltaFlags(Object e) {
/*
* Launch deltas for standard platform DebugEvent events are handled by
* org.eclipse.debug.internal.ui.viewers.update.LaunchManagerProxy.
* Here only control the deltas of child nodes. This is necessary to avoid
* IProcess layout node from processing events that are intended for a
* different launch. This is not a problem with DMC events, because the
* full path of the DMC object is built into the DMC itself.
*/
if (e instanceof DebugEvent) {
DebugEvent de = (DebugEvent)e;
if (de.getSource() instanceof IProcess) {
return ((IProcess)de.getSource()).getLaunch().equals(getRootVMC().getInputObject()) && super.hasDeltaFlags(e);
} else if (de.getSource() instanceof IDebugElement) {
return ((IDebugElement)de.getSource()).getLaunch().equals(getRootVMC().getInputObject()) && super.hasDeltaFlags(e);
}
}
return super.hasDeltaFlags(e);
}
public void createDelta(Object event, final GetDataDone<IModelDelta> done) {
/*
* Create the root of the delta. Since the launch object is not at the
* root of the view, create the delta with the path to the launch, then
* pass that to the child layout nodes.
*/
final VMDelta delta = new VMDelta(DebugPlugin.getDefault().getLaunchManager(), null);
done.setData(delta);
final VMDelta rootDelta = delta.addNode(getRootVMC().getInputObject(), getRootVMC());
final IVMLayoutNode[] childNodes = getChildNodesWithDeltas(event);
if (childNodes.length == 0) {
done.setData(delta);
getExecutor().execute(done);
return;
}
/*
* The execution for this node is not done until all the child nodes
* are done. Use the tracker to wait for all children to complete.
*/
final DoneCollector doneCollector = new DoneCollector(getExecutor()) {
public void run() {
if (propagateError(getExecutor(), done, "Failed to generate child deltas.")) return;
done.setData(delta);
getExecutor().execute(done);
}
};
for (final IVMLayoutNode childNode : childNodes) {
childNode.buildDelta(event, rootDelta, doneCollector.addNoActionDone());
}
}
public IRootVMC getRootVMC() {
return fRootVMC;
}
}

View file

@ -0,0 +1,192 @@
/*******************************************************************************
* 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.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.dd.dsf.concurrent.Done;
import org.eclipse.dd.dsf.concurrent.DsfExecutor;
import org.eclipse.dd.dsf.concurrent.GetDataDone;
import org.eclipse.dd.dsf.debug.ui.DsfDebugUIPlugin;
import org.eclipse.dd.dsf.service.IDsfService;
import org.eclipse.dd.dsf.ui.viewmodel.AbstractVMLayoutNode;
import org.eclipse.dd.dsf.ui.viewmodel.IVMContext;
import org.eclipse.dd.dsf.ui.viewmodel.IVMLayoutNode;
import org.eclipse.dd.dsf.ui.viewmodel.VMDelta;
import org.eclipse.dd.dsf.ui.viewmodel.IVMRootLayoutNode.IRootVMC;
import org.eclipse.debug.core.DebugEvent;
import org.eclipse.debug.core.DebugException;
import org.eclipse.debug.core.ILaunch;
import org.eclipse.debug.core.model.IProcess;
import org.eclipse.debug.core.model.IStreamsProxy;
import org.eclipse.debug.internal.ui.viewers.provisional.ILabelRequestMonitor;
import org.eclipse.debug.internal.ui.viewers.provisional.IModelDelta;
/**
* Layout node for the standard platform debug model IProcess object. This
* node requires that an ILaunch object be found as an ancestor of this node.
* It does not implement the label provider functionality, so the default
* adapters should be used to retrieve the label.
*/
@SuppressWarnings("restriction")
public class StandardProcessLayoutNode extends AbstractVMLayoutNode {
/**
* VMC element implementation, it is a proxy for the IProcess class, to
* allow the standard label adapter to be used with this object.
*/
private class VMC implements IVMContext, IProcess
{
private final IVMContext fParentVmc;
private final IProcess fProcess;
VMC(IVMContext parentVmc, IProcess process) {
fParentVmc = parentVmc;
fProcess = process;
}
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 String getAttribute(String key) { return fProcess.getAttribute(key); }
public int getExitValue() throws DebugException { return fProcess.getExitValue(); }
public String getLabel() { return fProcess.getLabel(); }
public ILaunch getLaunch() { return fProcess.getLaunch(); }
public IStreamsProxy getStreamsProxy() { return fProcess.getStreamsProxy(); }
public void setAttribute(String key, String value) { fProcess.setAttribute(key, value); }
public boolean canTerminate() { return fProcess.canTerminate(); }
public boolean isTerminated() { return fProcess.isTerminated(); }
public void terminate() throws DebugException { fProcess.terminate(); }
public boolean equals(Object other) { return fProcess.equals(other); }
public int hashCode() { return fProcess.hashCode(); }
}
public StandardProcessLayoutNode(DsfExecutor executor) {
super(executor);
}
// @see org.eclipse.dd.dsf.ui.viewmodel.IViewModelLayoutNode#getElements(org.eclipse.dd.dsf.ui.viewmodel.IVMContext, org.eclipse.dd.dsf.concurrent.GetDataDone)
public void getElements(IVMContext parentVmc, GetDataDone<IVMContext[]> done) {
ILaunch launch = findLaunch(parentVmc);
if (launch == null) {
/*
* There is no launch in the parent of this node. This means that the
* 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));
getExecutor().execute(done);
return;
}
/*
* Assume that the process objects are stored within the launch, and
* retrieve them on dispatch thread.
*/
IProcess[] processes = launch.getProcesses();
IVMContext[] processVmcs = new IVMContext[processes.length];
for (int i = 0; i < processes.length; i++) {
processVmcs[i] = new VMC(parentVmc, processes[i]);
}
done.setData(processVmcs);
getExecutor().execute(done);
}
// @see org.eclipse.dd.dsf.ui.viewmodel.IViewModelLayoutNode#hasElements(org.eclipse.dd.dsf.ui.viewmodel.IVMContext, org.eclipse.dd.dsf.concurrent.GetDataDone)
public void hasElements(IVMContext parentVmc, GetDataDone<Boolean> done) {
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));
getExecutor().execute(done);
return;
}
done.setData(launch.getProcesses().length != 0);
getExecutor().execute(done);
}
// @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) {
/*
* The implementation of IAdapterFactory that uses this node should not
* register a label adapter for IProcess. This will cause the default
* label provider to be used instead, and this method should then never
* be called.
*/
assert false;
result.done();
}
/**
* Recursively searches the VMC for Launch VMC, and returns its ILaunch.
* Returns null if an ILaunch is not found.
*/
private ILaunch findLaunch(IVMContext vmc) {
if (vmc == null) {
return null;
} else if (vmc instanceof IRootVMC || ((IRootVMC)vmc).getInputObject() instanceof ILaunch) {
return (ILaunch)(((IRootVMC)vmc)).getInputObject();
} else {
return findLaunch(vmc.getParent());
}
}
@Override
public boolean hasDeltaFlags(Object e) {
if (e instanceof DebugEvent) {
DebugEvent de = (DebugEvent)e;
return de.getSource() instanceof IProcess &&
(de.getKind() == DebugEvent.CHANGE ||
de.getKind() == DebugEvent.CREATE ||
de.getKind() == DebugEvent.TERMINATE);
}
return super.hasDeltaFlags(e);
}
@Override
public void buildDelta(Object e, VMDelta parent, Done done) {
if (e instanceof DebugEvent && ((DebugEvent)e).getSource() instanceof IProcess) {
DebugEvent de = (DebugEvent)e;
if (de.getKind() == DebugEvent.CHANGE) {
handleChange(de, parent);
} else if (de.getKind() == DebugEvent.CREATE) {
handleCreate(de, parent);
} else if (de.getKind() == DebugEvent.TERMINATE) {
handleTerminate(de, parent);
}
/*
* No other node should need to process events related to process.
* Therefore, just invoke done, without calling super.buildDelta().
*/
getExecutor().execute(done);
} else {
super.buildDelta(e, parent, done);
}
}
protected void handleChange(DebugEvent event, VMDelta parent) {
parent.addNode(new VMC(parent.getVMC(), (IProcess)event.getSource()), IModelDelta.STATE);
}
protected void handleCreate(DebugEvent event, VMDelta parent) {
// do nothing - Launch change notification handles this
}
protected void handleTerminate(DebugEvent event, VMDelta parent) {
handleChange(event, parent);
}
}

View file

@ -0,0 +1,99 @@
/*******************************************************************************
* 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.concurrent.Done;
import org.eclipse.dd.dsf.concurrent.GetDataDone;
import org.eclipse.dd.dsf.datamodel.IDMEvent;
import org.eclipse.dd.dsf.debug.service.INativeProcesses;
import org.eclipse.dd.dsf.debug.service.IRunControl;
import org.eclipse.dd.dsf.debug.service.INativeProcesses.IThreadDMData;
import org.eclipse.dd.dsf.debug.service.IRunControl.IExecutionDMContext;
import org.eclipse.dd.dsf.mi.service.MIRunControl;
import org.eclipse.dd.dsf.service.DsfSession;
import org.eclipse.dd.dsf.ui.viewmodel.DMContextVMLayoutNode;
import org.eclipse.dd.dsf.ui.viewmodel.GetDataDoneWithRequestMonitor;
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.debug.internal.ui.viewers.provisional.IModelDelta;
import org.eclipse.debug.ui.DebugUITools;
import org.eclipse.debug.ui.IDebugUIConstants;
import org.eclipse.jface.resource.ImageDescriptor;
@SuppressWarnings("restriction")
public class ThreadLayoutNode extends DMContextVMLayoutNode {
public ThreadLayoutNode(DsfSession session) {
super(session, IRunControl.IExecutionDMContext.class);
}
public void hasElements(IVMContext parentVmc, final GetDataDone<Boolean> done) {
done.setData(Boolean.TRUE);
getExecutor().execute(done);
}
public void getElements(final IVMContext parentVmc, final GetDataDone<IVMContext[]> done) {
if (getServicesTracker().getService(MIRunControl.class) == null) {
done.setData(new IVMContext[0]);
getExecutor().execute(done);
return;
}
IExecutionDMContext execCtx = getServicesTracker().getService(MIRunControl.class).getExecutionDMC();
done.setData(dmcs2vmcs(parentVmc, new IExecutionDMContext[] { execCtx }));
getExecutor().execute(done);
}
public void retrieveLabel(IVMContext vmc, final ILabelRequestMonitor result) {
IExecutionDMContext dmc = (IExecutionDMContext)((DMContextVMContext)vmc).getDMC();
INativeProcesses processes = getServicesTracker().getService(INativeProcesses.class);
String imageKey = null;
IRunControl rc = getServicesTracker().getService(IRunControl.class);
if (rc.isSuspended(dmc)) {
imageKey = IDebugUIConstants.IMG_OBJS_THREAD_SUSPENDED;
} else {
imageKey = IDebugUIConstants.IMG_OBJS_THREAD_RUNNING;
}
result.setImageDescriptors(new ImageDescriptor[] { DebugUITools.getImageDescriptor(imageKey) });
processes.getModelData(
processes.getThreadForExecutionContext(dmc),
new GetDataDoneWithRequestMonitor<IThreadDMData>(result) { public void doRun() {
result.setLabels(new String[] { getData().getName() });
}});
}
public boolean hasDeltaFlagsForDMEvent(IDMEvent e) {
// This node generates delta if the timers have changed, or if the
// label has changed.
return e instanceof IRunControl.IResumedDMEvent ||
e instanceof IRunControl.ISuspendedDMEvent ||
super.hasDeltaFlagsForDMEvent(e);
}
public void buildDeltaForDMEvent(final IDMEvent e, final VMDelta parent, final Done done) {
if (e instanceof IRunControl.IResumedDMEvent) {
// Add delta indicating that the VMC for the given timer context
// has changed.
parent.addNode(
new DMContextVMContext(parent.getVMC(), e.getDMContext()),
IModelDelta.STATE);
} else if (e instanceof IRunControl.ISuspendedDMEvent) {
parent.addNode(
new DMContextVMContext(parent.getVMC(), e.getDMContext()),
IModelDelta.STATE);
}
super.buildDeltaForDMEvent(e, parent, done);
}
}

View file

@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry kind="src" path="src"/>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/J2SE-1.5"/>
<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
<classpathentry kind="output" path="bin/classes"/>
</classpath>

View file

@ -0,0 +1 @@

View file

@ -0,0 +1,2 @@
org.eclipse.dd.dsf/debug = false
org.eclipse.dd.dsf/debug/executor = false

View file

@ -0,0 +1,28 @@
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>org.eclipse.dd.dsf.debug</name>
<comment></comment>
<projects>
</projects>
<buildSpec>
<buildCommand>
<name>org.eclipse.jdt.core.javabuilder</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>org.eclipse.pde.ManifestBuilder</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>org.eclipse.pde.SchemaBuilder</name>
<arguments>
</arguments>
</buildCommand>
</buildSpec>
<natures>
<nature>org.eclipse.pde.PluginNature</nature>
<nature>org.eclipse.jdt.core.javanature</nature>
</natures>
</projectDescription>

View file

@ -0,0 +1,12 @@
#Thu Jul 27 15:22:22 PDT 2006
eclipse.preferences.version=1
org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.5
org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
org.eclipse.jdt.core.compiler.compliance=1.5
org.eclipse.jdt.core.compiler.debug.lineNumber=generate
org.eclipse.jdt.core.compiler.debug.localVariable=generate
org.eclipse.jdt.core.compiler.debug.sourceFile=generate
org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
org.eclipse.jdt.core.compiler.source=1.5

View file

@ -0,0 +1,3 @@
#Sun Aug 06 18:10:27 CEST 2006
eclipse.preferences.version=1
internal.default.compliance=default

View file

@ -0,0 +1,14 @@
Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: %pluginName
Bundle-Vendor: %providerName
Bundle-SymbolicName: org.eclipse.dd.dsf.debug
Bundle-Version: 1.0.0
Bundle-Activator: org.eclipse.dd.dsf.debug.DsfDebugPlugin
Bundle-Localization: plugin
Require-Bundle: org.eclipse.core.runtime,
org.eclipse.debug.core,
org.eclipse.dd.dsf
Eclipse-LazyStart: true
Export-Package: org.eclipse.dd.dsf.debug.service
Bundle-RequiredExecutionEnvironment: J2SE-1.5

View file

@ -0,0 +1,5 @@
source.. = src/
output.. = bin/
bin.includes = META-INF/,\
.,\
plugin.xml

View file

@ -0,0 +1,13 @@
###############################################################################
# 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
###############################################################################
pluginName=DSDP/DD Debugger Services Framework (DSF) Debug Services
providerName=Eclipse.org

View file

@ -0,0 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<?eclipse version="3.2"?>
<plugin>
</plugin>

View file

@ -0,0 +1,79 @@
/*******************************************************************************
* 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;
import org.eclipse.core.runtime.Platform;
import org.eclipse.core.runtime.Plugin;
import org.osgi.framework.BundleContext;
/**
* The activator class controls the plug-in life cycle
*/
public class DsfDebugPlugin extends Plugin {
// The plug-in ID
public static final String PLUGIN_ID = "org.eclipse.dd.dsf.debug.debug.service";
// The shared instance
private static DsfDebugPlugin fgPlugin;
// BundleContext of this plugin
private static BundleContext fgBundleContext;
// Debugging flag
public static boolean DEBUG = false;
/**
* The constructor
*/
public DsfDebugPlugin() {
fgPlugin = this;
}
/*
* (non-Javadoc)
* @see org.eclipse.core.runtime.Plugins#start(org.osgi.framework.BundleContext)
*/
public void start(BundleContext context) throws Exception {
fgBundleContext = context;
super.start(context);
DEBUG = "true".equals(Platform.getDebugOption("org.eclipse.dd.dsf.debug.debug.service/debug")); //$NON-NLS-1$//$NON-NLS-2$
}
/*
* (non-Javadoc)
* @see org.eclipse.core.runtime.Plugin#stop(org.osgi.framework.BundleContext)
*/
public void stop(BundleContext context) throws Exception {
fgPlugin = null;
fgBundleContext = null;
super.stop(context);
}
/**
* Returns the shared instance
*
* @return the shared instance
*/
public static DsfDebugPlugin getDefault() {
return fgPlugin;
}
public static BundleContext getBundleContext() {
return fgBundleContext;
}
public static void debug(String message) {
if (DEBUG) {
System.out.println(message);
}
}
}

View file

@ -1,4 +1,4 @@
package org.eclipse.dd.dsf.debug;
package org.eclipse.dd.dsf.debug.service;
/**
* I was told that BigInteger was not sufficient to represent an address, so

View file

@ -8,7 +8,7 @@
* Contributors:
* Wind River Systems - initial API and implementation
*******************************************************************************/
package org.eclipse.dd.dsf.debug;
package org.eclipse.dd.dsf.debug.service;
import org.eclipse.dd.dsf.service.IDsfService;

View file

@ -8,13 +8,13 @@
* Contributors:
* Wind River Systems - initial API and implementation
*******************************************************************************/
package org.eclipse.dd.dsf.debug;
package org.eclipse.dd.dsf.debug.service;
import org.eclipse.dd.dsf.concurrent.GetDataDone;
import org.eclipse.dd.dsf.debug.IRunControl.IExecutionDMC;
import org.eclipse.dd.dsf.model.IDataModelContext;
import org.eclipse.dd.dsf.model.IDataModelData;
import org.eclipse.dd.dsf.model.IDataModelEvent;
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.debug.service.IRunControl.IExecutionDMContext;
import org.eclipse.dd.dsf.service.IDsfService;
import org.eclipse.debug.core.model.IBreakpoint;
@ -29,22 +29,22 @@ public interface IBreakpoints extends IDsfService {
public enum BreakpointStatus { INSTALLED, FAILED_TO_INSTALL, FILTERED_OUT }
public interface IBreakpointDMC extends IDataModelContext<IBreakpointData> {}
public interface IBreakpointDMContext extends IDMContext<IBreakpointDMData> {}
public interface IBreakpointData extends IDataModelData {
public interface IBreakpointDMData extends IDMData {
IBreakpoint getPlatformBreakpoint();
BreakpointStatus getStatus();
}
public interface IBreakpointEvent extends IDataModelEvent<IBreakpointDMC> {}
public interface IBreakpointDMEvent extends IDMEvent<IBreakpointDMContext> {}
public interface IBreakpointInstalledEvent extends IBreakpointEvent {}
public interface IBreakpointUninstalledEvent extends IBreakpointEvent {}
public interface IBreakpointInstallFailedEvent extends IBreakpointEvent {}
public interface IBreakpointInstalledDMEvent extends IBreakpointDMEvent {}
public interface IBreakpointUninstalledDMEvent extends IBreakpointDMEvent {}
public interface IBreakpointInstallFailedDMEvent extends IBreakpointDMEvent {}
public interface IBreakpointHitEvent extends IBreakpointEvent {}
public interface IBreakpointHitEvent extends IBreakpointDMEvent {}
public void getAllBreakpoints(IExecutionDMC execDmc, GetDataDone<IBreakpointDMC[]> done);
public void getBreakpoints(IExecutionDMC execDmc, IBreakpoint platformBp, GetDataDone<IBreakpointDMC[]> done);
public void getAllBreakpoints(IExecutionDMContext execDmc, GetDataDone<IBreakpointDMContext[]> done);
public void getBreakpoints(IExecutionDMContext execDmc, IBreakpoint platformBp, GetDataDone<IBreakpointDMContext[]> done);
}

View file

@ -8,15 +8,15 @@
* Contributors:
* Wind River Systems - initial API and implementation
*******************************************************************************/
package org.eclipse.dd.dsf.debug;
package org.eclipse.dd.dsf.debug.service;
import java.util.Map;
import org.eclipse.dd.dsf.concurrent.GetDataDone;
import org.eclipse.dd.dsf.model.IDataModelContext;
import org.eclipse.dd.dsf.model.IDataModelData;
import org.eclipse.dd.dsf.model.IDataModelEvent;
import org.eclipse.dd.dsf.model.IDataModelService;
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;
/**
* Expressions service provides access to the debugger's expression evaluator.
@ -24,14 +24,14 @@ import org.eclipse.dd.dsf.model.IDataModelService;
* Stack service, as all may be used to provide context for an expression to be
* evaluated.
*/
public interface IExpressions extends IDataModelService {
public interface IExpressions extends IDMService {
/**
* Expression context. Since some expressions have children, expression
* contexts can be have an arbitrary number of parents of type
* ExpressionContext.
*/
public interface IExpressionDMC extends IDataModelContext<IExpressionData> {
public interface IExpressionDMContext extends IDMContext<IExpressionDMData> {
String getExpression();
}
@ -39,7 +39,7 @@ public interface IExpressions extends IDataModelService {
* Expression data. It is based pretty closely on what DFW's info-retrieve
* node for expressions.
*/
public interface IExpressionData extends IDataModelData {
public interface IExpressionDMData extends IDMData {
String getName();
public enum BasicType { basic, pointer, array, composite, enumeration, function }
BasicType getBasicType();
@ -53,7 +53,7 @@ public interface IExpressions extends IDataModelService {
String getBinaryValue();
String getStringValue();
IAddress getAddress();
IRegisters.IRegisterDMC getRegister();
IRegisters.IRegisterDMContext getRegister();
Map<String,String> getEnumerations();
}
@ -62,7 +62,7 @@ public interface IExpressions extends IDataModelService {
* is changed, it's implied that all the children of that expression are
* changed too.
*/
public interface IExpressionChangedEvent extends IDataModelEvent<IExpressionDMC> {}
public interface IExpressionChangedDMEvent extends IDMEvent<IExpressionDMContext> {}
/**
* Returns the context for the specified expression.
@ -72,7 +72,7 @@ public interface IExpressions extends IDataModelService {
* @param expression Expression to evaluate.
* @return Expression context.
*/
IExpressionDMC getExpressionContext(IModules.ISymbolDMC symCtx, IRunControl.IExecutionDMC execCtx, IStack.IFrameDMC frameCtx, String expression);
IExpressionDMContext createExpression(IModules.ISymbolDMContext symCtx, IRunControl.IExecutionDMContext execDmc, IStack.IFrameDMContext frameDmc, String expression);
/**
* Retrieves the sub-expressions of the given expression.
@ -80,7 +80,7 @@ public interface IExpressions extends IDataModelService {
* @param done The return parameter is an Iterable because it's possible
* that the sub-expressions as members of an array which could be very large.
*/
void getSubExpressions(IExpressionDMC exprCtx, GetDataDone<Iterable<IExpressionDMC>> done);
void getSubExpressions(IExpressionDMContext exprCtx, GetDataDone<Iterable<IExpressionDMContext>> done);
/**
* For object oriented languages, this method returns the expressions
@ -88,5 +88,5 @@ public interface IExpressions extends IDataModelService {
* @param exprContext
* @param done
*/
void getBaseExpressions(IExpressionDMC exprContext, GetDataDone<IExpressionDMC[]> done);
void getBaseExpressions(IExpressionDMContext exprContext, GetDataDone<IExpressionDMContext[]> done);
}

View file

@ -8,7 +8,7 @@
* Contributors:
* Wind River Systems - initial API and implementation
*******************************************************************************/
package org.eclipse.dd.dsf.debug;
package org.eclipse.dd.dsf.debug.service;
import org.eclipse.dd.dsf.concurrent.Done;
import org.eclipse.dd.dsf.service.IDsfService;
@ -16,7 +16,7 @@ import org.eclipse.dd.dsf.service.IDsfService;
/**
* Service for accessing memory. Memory contexts are not meant to be
* represented in tree or table views, so it doesn't need to implement
* IDataModelService interface.
* IDMService interface.
*/
public interface IMemory extends IDsfService {

View file

@ -8,21 +8,21 @@
* Contributors:
* Wind River Systems - initial API and implementation
*******************************************************************************/
package org.eclipse.dd.dsf.debug;
package org.eclipse.dd.dsf.debug.service;
import java.math.BigInteger;
import org.eclipse.dd.dsf.concurrent.GetDataDone;
import org.eclipse.dd.dsf.debug.IMemory.IAddress;
import org.eclipse.dd.dsf.model.IDataModelContext;
import org.eclipse.dd.dsf.model.IDataModelData;
import org.eclipse.dd.dsf.model.IDataModelEvent;
import org.eclipse.dd.dsf.model.IDataModelService;
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.debug.service.IMemory.IAddress;
/**
* Debugger service representing module handling logic of a debugger.
*/
public interface IModules extends IDataModelService {
public interface IModules extends IDMService {
/**
* Symbol context represents the space into which module symbols are loaded.
@ -30,30 +30,30 @@ public interface IModules extends IDataModelService {
* types of debugging, like kernel or no-OS debugging, it's useful to
* separate the concept of a symbol context from a process.
*/
public interface ISymbolDMC extends IDataModelContext {}
public interface ISymbolDMContext extends IDMContext {}
/**
* Module context represents a single module that is loaded.
*/
public interface IModuleDMC extends IDataModelContext<ModuleData> {}
public interface IModuleDMContext extends IDMContext<ModuleDMData> {}
/**
* Event indicating a change in the symbol information for given context.
*/
public interface ModulesChangedEvent extends IDataModelEvent<ISymbolDMC> {}
public interface ModulesChangedDMEvent extends IDMEvent<ISymbolDMContext> {}
/**
* Specific event identifying that a new module was loaded into a
* symbol context.
*/
public interface ModuleLoadedEvent extends ModulesChangedEvent {
public interface ModuleLoadedDMEvent extends ModulesChangedDMEvent {
/** Returns context of the module that was loaded */
IModuleDMC getLoadedModuleContext();
IModuleDMContext getLoadedModuleContext();
}
public interface ModuleUnloadedEvent extends ModulesChangedEvent {
public interface ModuleUnloadedDMEvent extends ModulesChangedDMEvent {
/** Returns context of the module that was un-loaded */
IModuleDMC getUnloadedModuleContext();
IModuleDMContext getUnloadedModuleContext();
}
/**
@ -61,15 +61,15 @@ public interface IModules extends IDataModelService {
* a module, section, and address offset within the seciton.
*/
public final class ModuleSectionOffset {
private final IModuleDMC fModule;
private final IModuleDMContext fModule;
private final Section fSection;
private final BigInteger fOffset;
public IModuleDMC getModule() { return fModule; }
public IModuleDMContext getModule() { return fModule; }
public Section getSection() { return fSection; }
public BigInteger getOffset() { return fOffset; }
public ModuleSectionOffset(IModuleDMC module, Section section, BigInteger offset) {
public ModuleSectionOffset(IModuleDMContext module, Section section, BigInteger offset) {
this.fModule = module;
this.fSection = section;
this.fOffset = offset;
@ -90,7 +90,7 @@ public interface IModules extends IDataModelService {
* Symbol context data includes a mapping between run-time addresses and
* module-section-offset coordinates.
*/
public interface SymbolData extends IDataModelData {
public interface SymbolDMData extends IDMData {
/** Convert link-time address 'addr' to run-time address */
public long convertToRT(ModuleSectionOffset mso);
@ -99,7 +99,7 @@ public interface IModules extends IDataModelService {
}
/** Module information. */
public interface ModuleData extends IDataModelData {
public interface ModuleDMData extends IDMData {
String getName();
String getFile();
long getTimeStamp();
@ -132,16 +132,16 @@ public interface IModules extends IDataModelService {
/**
* Retreives the list of modules loaded in given symbol context.
*/
void getModules(ISymbolDMC symCtx, GetDataDone<IModuleDMC[]> done);
void getModules(ISymbolDMContext symCtx, GetDataDone<IModuleDMContext[]> done);
/**
* Calculates the line numbers corresponding to the given address.
*/
void calcLineInfo(ISymbolDMC symCtx, IAddress address, GetDataDone<LineInfo[]> done);
void calcLineInfo(ISymbolDMContext symCtx, IAddress address, GetDataDone<LineInfo[]> done);
/**
* Calculates the addresses corresponding to the given source file location.
*/
void calcAddressInfo(ISymbolDMC symCtx, String file, int line, int col, GetDataDone<AddressRange[]> done);
void calcAddressInfo(ISymbolDMContext symCtx, String file, int line, int col, GetDataDone<AddressRange[]> done);
}

View file

@ -8,14 +8,14 @@
* Contributors:
* Wind River Systems - initial API and implementation
*******************************************************************************/
package org.eclipse.dd.dsf.debug;
package org.eclipse.dd.dsf.debug.service;
import org.eclipse.dd.dsf.concurrent.Done;
import org.eclipse.dd.dsf.concurrent.GetDataDone;
import org.eclipse.dd.dsf.model.IDataModelContext;
import org.eclipse.dd.dsf.model.IDataModelData;
import org.eclipse.dd.dsf.model.IDataModelEvent;
import org.eclipse.dd.dsf.model.IDataModelService;
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;
/**
* This interface provides access to the native OS's process
@ -24,78 +24,78 @@ import org.eclipse.dd.dsf.model.IDataModelService;
* manipulating processes as compared with a full-blown
* remote target debugger.
*/
public interface INativeProcesses extends IDataModelService {
public interface INativeProcesses extends IDMService {
public interface IThreadDMC extends IDataModelContext<IThreadData> {}
public interface IProcessDMC extends IThreadDMC {}
public interface IThreadDMContext extends IDMContext<IThreadDMData> {}
public interface IProcessDMContext extends IThreadDMContext {}
/**
* Interface for thread and process object data. This data provides a link
* to the lower level debugger services, in form of symbol, memory, and
* execution contexts.
*/
public interface IThreadData extends IDataModelData {
public interface IThreadDMData extends IDMData {
String getName();
String getId();
boolean isDebuggerAttached();
IRunControl.IExecutionDMC getExecutionContext();
IRunControl.IExecutionDMContext getExecutionContext();
IMemory.IMemoryContext getMemoryContext();
IModules.ISymbolDMC getSymbolContext();
IModules.ISymbolDMContext getSymbolContext();
}
/**
* Event indicating that process data has changed.
*/
public interface ProcessChangedEvent extends IDataModelEvent<IProcessDMC> {}
public interface ProcessChangedDMEvent extends IDMEvent<IProcessDMContext> {}
/**
* Retrieves the current list of processes running on target.
*/
void getRunningProcesses(GetDataDone<IProcessDMC[]> done);
void getRunningProcesses(GetDataDone<IProcessDMContext[]> done);
/**
* Attaches debugger to the given process.
*/
void attachDebuggerToProcess(IProcessDMC procCtx, Done done);
void attachDebuggerToProcess(IProcessDMContext procCtx, Done done);
/**
* Starts a new process.
* @param file Process image to use for the new process.
* @param done Return token with the process context.
*/
void runNewProcess(String file, GetDataDone<IProcessDMC> done);
void runNewProcess(String file, GetDataDone<IProcessDMContext> done);
/**
* Starts a new process with debugger attached.
* @param file Process image to use for the new process.
* @param done Return token with the process context.
*/
void debugNewProcess(String file, GetDataDone<IProcessDMC> done);
void debugNewProcess(String file, GetDataDone<IProcessDMContext> done);
/**
* Retrieves the list of processes which are currently under
* debugger control.
*/
void getProcessesBeingDebugged(GetDataDone<IProcessDMC[]> done);
void getProcessesBeingDebugged(GetDataDone<IProcessDMContext[]> done);
/**
* Returns a thread context for given run control execution context.
* @param execCtx Execution context to return thread for.
* @return Corresponding thread context.
*/
IThreadDMC getThreadForExecutionContext(IRunControl.IExecutionDMC execCtx);
IThreadDMContext getThreadForExecutionContext(IRunControl.IExecutionDMContext execCtx);
/**
* Checks whether the given process or thread can be terminated.
* @param thread Thread or process to terminate.
* @param done Return token.
*/
void canTerminate(IThreadDMC thread, GetDataDone<Boolean> done);
void canTerminate(IThreadDMContext thread, GetDataDone<Boolean> done);
/**
* Terminates the selected process or thread.
* @param thread Thread or process to terminate.
* @param done Return token.
*/
void terminate(IThreadDMC thread, Done done);
void terminate(IThreadDMContext thread, Done done);
}

View file

@ -8,13 +8,13 @@
* Contributors:
* Wind River Systems - initial API and implementation
*******************************************************************************/
package org.eclipse.dd.dsf.debug;
package org.eclipse.dd.dsf.debug.service;
import org.eclipse.dd.dsf.concurrent.Done;
import org.eclipse.dd.dsf.concurrent.GetDataDone;
import org.eclipse.dd.dsf.model.IDataModelContext;
import org.eclipse.dd.dsf.model.IDataModelData;
import org.eclipse.dd.dsf.model.IDataModelService;
import org.eclipse.dd.dsf.datamodel.IDMContext;
import org.eclipse.dd.dsf.datamodel.IDMData;
import org.eclipse.dd.dsf.datamodel.IDMService;
/**
* Provides generic access to operating system objects and methods to
@ -24,18 +24,18 @@ import org.eclipse.dd.dsf.model.IDataModelService;
*
* @see INativeProcesses
*/
public interface IOS extends IDataModelService {
public interface IOS extends IDMService {
/**
* Context object for the whole OS, for debuggers that support
* debugging multiple targets/cores simultaneously.
*/
public interface IOSDMC extends IDataModelContext<IOSData> {}
public interface IOSDMContext extends IDMContext<IOSDMData> {}
/**
* Data object describing OS info
*/
public interface IOSData extends IDataModelData {
public interface IOSDMData extends IDMData {
String getName();
String getDescription();
String getVersion();
@ -44,12 +44,12 @@ public interface IOS extends IDataModelService {
/**
* Context for a OS object type, such as process, kernel task, semaphore, etc.
*/
public interface IObjectTypeDMC extends IDataModelContext<IObjectTypeData> {}
public interface IObjectTypeDMContext extends IDMContext<IObjectTypeDMData> {}
/**
* Description data for a OS object type.
*/
public interface IObjectTypeData extends IDataModelData {
public interface IObjectTypeDMData extends IDMData {
String getName();
String getDescription();
String getSingularName();
@ -62,18 +62,18 @@ public interface IOS extends IDataModelService {
/**
* OS object context.
*/
public interface IObjectDMC extends IDataModelContext<IObjectData> {}
public interface IObjectDMContext extends IDMContext<IObjectDMData> {}
/**
* Description data for an OS object.
*/
public interface IObjectData extends IDataModelData {
public interface IObjectDMData extends IDMData {
String getName();
String getID();
boolean canAttachDebugger();
boolean isDebuggerAttached();
IRunControl.IExecutionDMC getExecutionDMC();
IModules.ISymbolDMC getSymbolDMC();
IRunControl.IExecutionDMContext getExecutionDMC();
IModules.ISymbolDMContext getSymbolDMC();
IMemory.IMemoryContext getMemoryContext();
}
@ -83,7 +83,7 @@ public interface IOS extends IDataModelService {
* @param parent Optional parent type.
* @param done Return token.
*/
public void getObjectTypes(IOSDMC os, IObjectTypeDMC parent, GetDataDone<IObjectTypeDMC[]> done);
public void getObjectTypes(IOSDMContext os, IObjectTypeDMContext parent, GetDataDone<IObjectTypeDMContext[]> done);
/**
* Retrieves list of OS objects for given type.
@ -92,10 +92,10 @@ public interface IOS extends IDataModelService {
* @param parent Optional parent of the requested objects.
* @param done Return token.
*/
public void getObjects(IOSDMC os, IObjectTypeDMC type, IObjectDMC parent, GetDataDone<IObjectDMC[]> done);
public void getObjects(IOSDMContext os, IObjectTypeDMContext type, IObjectDMContext parent, GetDataDone<IObjectDMContext[]> done);
/**
* Attaches the debugger to given OS object context.
*/
public void attachDebuggerToObject(IObjectDMC objectDmc, Done done);
public void attachDebuggerToObject(IObjectDMContext objectDmc, Done done);
}

View file

@ -8,39 +8,39 @@
* Contributors:
* Wind River Systems - initial API and implementation
*******************************************************************************/
package org.eclipse.dd.dsf.debug;
package org.eclipse.dd.dsf.debug.service;
import org.eclipse.dd.dsf.concurrent.GetDataDone;
import org.eclipse.dd.dsf.model.IDataModelContext;
import org.eclipse.dd.dsf.model.IDataModelData;
import org.eclipse.dd.dsf.model.IDataModelEvent;
import org.eclipse.dd.dsf.model.IDataModelService;
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;
/**
* Service for accessing register data.
*/
public interface IRegisters extends IDataModelService {
public interface IRegisters extends IDMService {
/** Register group context */
public interface IRegisterGroupDMC extends IDataModelContext<IRegisterGroupData> {}
public interface IRegisterGroupDMContext extends IDMContext<IRegisterGroupData> {}
/**
* Register groups only have a name. Sub groups and registered are retrieved
* through the service interface.
*/
public interface IRegisterGroupData extends IDataModelData {
public interface IRegisterGroupData extends IDMData {
public String getName();
public String getDescription();
}
/** Register context */
public interface IRegisterDMC extends IDataModelContext<IRegisterData> {}
public interface IRegisterDMContext extends IDMContext<IRegisterDMData> {}
/** Event indicating register value changed. */
public interface IRegisterChangedEvent extends IDataModelEvent<IRegisterDMC> {}
public interface IRegisterChangedDMEvent extends IDMEvent<IRegisterDMContext> {}
/** Register information */
public interface IRegisterData extends IDataModelData, INumericalValue {
public interface IRegisterDMData extends IDMData, INumericalValue {
String getName();
String getDescription();
boolean isReadable();
@ -53,13 +53,13 @@ public interface IRegisters extends IDataModelService {
}
/** Bit field context */
public interface IBitFieldDMC extends IDataModelContext<IBitFieldData> {}
public interface IBitFieldDMContext extends IDMContext<IBitFieldDMData> {}
/**
* Bitfield data, big groups and mnemonics are retrieved at the same
* time as rest of bit field data
*/
public interface IBitFieldData extends IDataModelData, INumericalValue {
public interface IBitFieldDMData extends IDMData, INumericalValue {
String getName();
String getDescription();
boolean isReadable();
@ -102,14 +102,14 @@ public interface IRegisters extends IDataModelService {
* @param frameCtx Stack frame DMC, this is optional and may be null.
* @param done Return token.
*/
void getRegisterGroups(IRunControl.IExecutionDMC execCtx, IStack.IFrameDMC frameCtx, GetDataDone<IRegisterGroupDMC[]> done);
void getRegisterGroups(IRunControl.IExecutionDMContext execCtx, IStack.IFrameDMContext frameCtx, GetDataDone<IRegisterGroupDMContext[]> done);
/** Retrieves list of sub-groups of given register group. */
void getRegisterSubGroups(IRegisterGroupDMC groupCtx, GetDataDone<IRegisterGroupDMC[]> done);
void getRegisterSubGroups(IRegisterGroupDMContext groupCtx, GetDataDone<IRegisterGroupDMContext[]> done);
/** Retrieves registers in given register group. */
void getRegisters(IRegisterGroupDMC groupCtx, GetDataDone<IRegisterDMC[]> done);
void getRegisters(IRegisterGroupDMContext groupCtx, GetDataDone<IRegisterDMContext[]> done);
/** Retrieves bit fields for given register */
void getBitFields(IRegisterDMC regCtx, GetDataDone<IBitFieldDMC[]> done);
void getBitFields(IRegisterDMContext regCtx, GetDataDone<IBitFieldDMContext[]> done);
}

View file

@ -8,14 +8,14 @@
* Contributors:
* Wind River Systems - initial API and implementation
*******************************************************************************/
package org.eclipse.dd.dsf.debug;
package org.eclipse.dd.dsf.debug.service;
import org.eclipse.dd.dsf.concurrent.Done;
import org.eclipse.dd.dsf.concurrent.GetDataDone;
import org.eclipse.dd.dsf.model.IDataModelContext;
import org.eclipse.dd.dsf.model.IDataModelData;
import org.eclipse.dd.dsf.model.IDataModelEvent;
import org.eclipse.dd.dsf.model.IDataModelService;
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;
/**
* This interface provides access to controlling and monitoring the execution
@ -25,21 +25,21 @@ import org.eclipse.dd.dsf.model.IDataModelService;
* higher level services, ones that deal with processes, kernels, or target
* features will provide that functionality.
*/
public interface IRunControl extends IDataModelService
public interface IRunControl extends IDMService
{
/**
* Execution context is the object on which run control operations can be
* performed. A lot of higher-level services reference this context to build
* functionality on top of it, e.g. stack, expression evaluation, registers, etc.
*/
public interface IExecutionDMC extends IDataModelContext<IExecutionData> {}
public interface IExecutionDMContext extends IDMContext<IExecutionDMData> {}
/**
* Context representing a process, kernel, or some other logical container
* for execution cotnexts, which by itself can perform run-control
* operations.
*/
public interface IContainerDMC extends IExecutionDMC {}
public interface IContainerDMContext extends IExecutionDMContext {}
/** Flag indicating reason context state change. */
public enum StateChangeReason { UNKNOWN, USER_REQUEST, STEP, BREAKPOINT, EXCEPTION, CONTAINER };
@ -47,16 +47,16 @@ public interface IRunControl extends IDataModelService
/**
* Events signaling a state changes.
*/
public interface ISuspendedEvent extends IDataModelEvent<IExecutionDMC> {
public interface ISuspendedDMEvent extends IDMEvent<IExecutionDMContext> {
StateChangeReason getReason();
}
public interface IResumedEvent extends IDataModelEvent<IExecutionDMC> {
public interface IResumedDMEvent extends IDMEvent<IExecutionDMContext> {
StateChangeReason getReason();
}
public interface IContainerSuspendedEvent extends IDataModelEvent<IExecutionDMC> {
public interface IContainerSuspendedDMEvent extends IDMEvent<IExecutionDMContext> {
StateChangeReason getReason();
}
public interface IContainerResumedEvent extends IDataModelEvent<IExecutionDMC> {
public interface IContainerResumedDMEvent extends IDMEvent<IExecutionDMContext> {
StateChangeReason getReason();
}
@ -64,43 +64,43 @@ public interface IRunControl extends IDataModelService
* Indicates that a new execution context (thread) was started. The DMC
* for the event is the container of the new exec context.
*/
public interface IStartedEvent extends IDataModelEvent<IContainerDMC> {
IExecutionDMC getExecutionContext();
public interface IStartedDMEvent extends IDMEvent<IContainerDMContext> {
IExecutionDMContext getExecutionContext();
}
/**
* Indicates that an execution context has exited. As in the started event,
* the DMC for the event is the container of the exec context.
*/
public interface IExitedEvent extends IDataModelEvent<IContainerDMC> {
IExecutionDMC getExecutionContext();
public interface IExitedDMEvent extends IDMEvent<IContainerDMContext> {
IExecutionDMContext getExecutionContext();
}
/**
* Display information for an execution context.
*/
public interface IExecutionData extends IDataModelData {
public interface IExecutionDMData extends IDMData {
StateChangeReason getStateChangeReason();
}
/**
* Returns execution contexts belonging to the given container context.
*/
public void getExecutionContexts(IContainerDMC c, GetDataDone<IExecutionDMC[]> done);
public void getExecutionContexts(IContainerDMContext c, GetDataDone<IExecutionDMContext[]> done);
/*
* Run control commands. They all require the IExecutionContext object on
* which they perform the operations.
*/
boolean canResume(IExecutionDMC context);
boolean canSuspend(IExecutionDMC context);
boolean isSuspended(IExecutionDMC context);
void resume(IExecutionDMC context, Done done);
void suspend(IExecutionDMC context, Done done);
boolean canResume(IExecutionDMContext context);
boolean canSuspend(IExecutionDMContext context);
boolean isSuspended(IExecutionDMContext context);
void resume(IExecutionDMContext context, Done done);
void suspend(IExecutionDMContext context, Done done);
public enum StepType { STEP_OVER, STEP_INTO, STEP_RETURN };
boolean isStepping(IExecutionDMC context);
boolean canStep(IExecutionDMC context);
void step(IExecutionDMC context, StepType stepType, Done done);
boolean canInstructionStep(IExecutionDMC context);
void instructionStep(IExecutionDMC context, StepType stepType, Done done);
boolean isStepping(IExecutionDMContext context);
boolean canStep(IExecutionDMContext context);
void step(IExecutionDMContext context, StepType stepType, Done done);
boolean canInstructionStep(IExecutionDMContext context);
void instructionStep(IExecutionDMContext context, StepType stepType, Done done);
}

View file

@ -8,7 +8,7 @@
* Contributors:
* Wind River Systems - initial API and implementation
*******************************************************************************/
package org.eclipse.dd.dsf.debug;
package org.eclipse.dd.dsf.debug.service;
import org.eclipse.dd.dsf.concurrent.GetDataDone;
import org.eclipse.dd.dsf.service.IDsfService;
@ -38,7 +38,7 @@ public interface ISourceLookup extends IDsfService {
}
/** Returns the source lookup context for the given modules context. */
ISourceLookupContext getContextForSymbolContext(IModules.ISymbolDMC symCtx);
ISourceLookupContext getContextForSymbolContext(IModules.ISymbolDMContext symCtx);
/**
* Initializes the given context with the given list of source lookup

View file

@ -8,31 +8,31 @@
* Contributors:
* Wind River Systems - initial API and implementation
*******************************************************************************/
package org.eclipse.dd.dsf.debug;
package org.eclipse.dd.dsf.debug.service;
import org.eclipse.dd.dsf.concurrent.GetDataDone;
import org.eclipse.dd.dsf.debug.IMemory.IAddress;
import org.eclipse.dd.dsf.model.IDataModelContext;
import org.eclipse.dd.dsf.model.IDataModelData;
import org.eclipse.dd.dsf.model.IDataModelService;
import org.eclipse.dd.dsf.datamodel.IDMContext;
import org.eclipse.dd.dsf.datamodel.IDMData;
import org.eclipse.dd.dsf.datamodel.IDMService;
import org.eclipse.dd.dsf.debug.service.IMemory.IAddress;
/**
* Stack service provides access to stack information for a
* given execution context.
*/
public interface IStack extends IDataModelService {
public interface IStack extends IDMService {
/**
* Context for a specific stack frame. Besides allowing access to stack
* frame data, this context is used by other services that require a stack
* frame for evaluation.
*/
public interface IFrameDMC extends IDataModelContext<IFrameData> {}
public interface IFrameDMContext extends IDMContext<IFrameDMData> {}
/**
* Stack frame information.
*/
public interface IFrameData extends IDataModelData {
public interface IFrameDMData extends IDMData {
int getLevel();
IAddress getAddress();
String getFile();
@ -46,12 +46,12 @@ public interface IStack extends IDataModelService {
* expression information. For displaying complete information,
* Expressions service should be used.
*/
public interface IVariableDMC extends IDataModelContext<IVariableData> {}
public interface IVariableDMContext extends IDMContext<IVariableDMData> {}
/**
* Stack frame variable information.
*/
public interface IVariableData extends IDataModelData {
public interface IVariableDMData extends IDMData {
String getName();
String getValue();
}
@ -59,13 +59,13 @@ public interface IStack extends IDataModelService {
/**
* Returns whether the stack frames can be retrieved for given thread.
*/
boolean isStackAvailable(IRunControl.IExecutionDMC execContext);
boolean isStackAvailable(IRunControl.IExecutionDMContext execContext);
/**
* Retrieves list of stack frames for the given execution context. Request
* will fail if the stack frame data is not available.
*/
void getFrames(IRunControl.IExecutionDMC execContext, GetDataDone<IFrameDMC[]> done);
void getFrames(IRunControl.IExecutionDMContext execContext, GetDataDone<IFrameDMContext[]> done);
/**
* Retrieves the top stack frame for the given execution context.
@ -76,15 +76,15 @@ public interface IStack extends IDataModelService {
* @param execContext
* @param done
*/
void getTopFrame(IRunControl.IExecutionDMC execContext, GetDataDone<IFrameDMC> done);
void getTopFrame(IRunControl.IExecutionDMContext execContext, GetDataDone<IFrameDMContext> done);
/**
* Retrieves variables which were arguments to the stack frame's function.
*/
void getArguments(IFrameDMC frameCtx, GetDataDone<IVariableDMC[]> done);
void getArguments(IFrameDMContext frameCtx, GetDataDone<IVariableDMContext[]> done);
/**
* Retrieves variables local to the stack frame.
*/
void getLocals(IFrameDMC frameCtx, GetDataDone<IVariableDMC[]> done);
void getLocals(IFrameDMContext frameCtx, GetDataDone<IVariableDMContext[]> done);
}

View file

@ -8,10 +8,10 @@
* Contributors:
* Wind River Systems - initial API and implementation
*******************************************************************************/
package org.eclipse.dd.dsf.debug;
package org.eclipse.dd.dsf.debug.service;
import org.eclipse.dd.dsf.debug.IRunControl.IExecutionDMC;
import org.eclipse.dd.dsf.model.IDataModelEvent;
import org.eclipse.dd.dsf.datamodel.IDMEvent;
import org.eclipse.dd.dsf.debug.service.IRunControl.IExecutionDMContext;
import org.eclipse.dd.dsf.service.IDsfService;
/**
@ -34,7 +34,7 @@ public interface IStepQueueManager extends IDsfService {
* Indicates that the given context has been stepping for some time,
* and the UI (views and actions) may need to be updated accordingly.
*/
public interface ISteppingTimedOutEvent extends IDataModelEvent<IExecutionDMC> {
public interface ISteppingTimedOutEvent extends IDMEvent<IExecutionDMContext> {
}
@ -45,21 +45,21 @@ public interface IStepQueueManager extends IDsfService {
* Returns the number of step commands that are queued for given execution
* context.
*/
int getPendingStepCount(IRunControl.IExecutionDMC execCtx);
int getPendingStepCount(IRunControl.IExecutionDMContext execCtx);
/**
* Checks whether a step command can be queued up for given context.
*/
boolean canEnqueueStep(IRunControl.IExecutionDMC execCtx);
boolean canEnqueueStep(IRunControl.IExecutionDMContext execCtx);
boolean canEnqueueInstructionStep(IRunControl.IExecutionDMC execCtx);
boolean canEnqueueInstructionStep(IRunControl.IExecutionDMContext execCtx);
/**
* Adds a step command to the execution queue for given context.
* @param execCtx Execution context that should perform the step.
* @param stepType Type of step to execute.
*/
void enqueueStep(IRunControl.IExecutionDMC execCtx, IRunControl.StepType stepType);
void enqueueStep(IRunControl.IExecutionDMContext execCtx, IRunControl.StepType stepType);
/**
* Adds an instruction step command to the execution queue for given
@ -67,7 +67,7 @@ public interface IStepQueueManager extends IDsfService {
* @param execCtx Execution context that should perform the step.
* @param stepType Type of step to execute.
*/
void enqueueInstructionStep(IRunControl.IExecutionDMC execCtx, IRunControl.StepType stepType);
void enqueueInstructionStep(IRunControl.IExecutionDMContext execCtx, IRunControl.StepType stepType);
boolean isSteppingTimedOut(IExecutionDMC context);
boolean isSteppingTimedOut(IExecutionDMContext context);
}

View file

@ -8,13 +8,13 @@
* Contributors:
* Wind River Systems - initial API and implementation
*******************************************************************************/
package org.eclipse.dd.dsf.debug;
package org.eclipse.dd.dsf.debug.service;
import org.eclipse.dd.dsf.concurrent.GetDataDone;
import org.eclipse.dd.dsf.model.IDataModelContext;
import org.eclipse.dd.dsf.model.IDataModelData;
import org.eclipse.dd.dsf.model.IDataModelEvent;
import org.eclipse.dd.dsf.model.IDataModelService;
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;
/**
* Service for accessing debugger symbols. This service builds on the Modules
@ -22,13 +22,13 @@ import org.eclipse.dd.dsf.model.IDataModelService;
* service is separated.
* @see IModules
*/
public interface ISymbols extends IDataModelService {
public interface ISymbolObjectDMC extends IDataModelContext<ISymbolObjectData> {}
public interface ISymbols extends IDMService {
public interface ISymbolObjectDMContext extends IDMContext<ISymbolObjectDMData> {}
/**
* Data about a debug symbol.
*/
public interface ISymbolObjectData extends IDataModelData {
public interface ISymbolObjectDMData extends IDMData {
String getName();
String getTypeName();
String getFilepath();
@ -42,7 +42,7 @@ public interface ISymbols extends IDataModelService {
* by the service to indicate that a section of debug symbols has been
* parsed.
*/
public interface ISymbolDataChanged extends IDataModelEvent<IModules.ISymbolDMC> {}
public interface ISymbolDataChangedDMEvent extends IDMEvent<IModules.ISymbolDMContext> {}
/**
* Retrieves the list of symbols.
@ -50,5 +50,5 @@ public interface ISymbols extends IDataModelService {
* @param done Return token. The return value is an iterator (rather than
* array) since there could be a very large number of symbols returned.
*/
public void getSymbols(IModules.ISymbolDMC symCtx, GetDataDone<Iterable<ISymbolObjectDMC>> done);
public void getSymbols(IModules.ISymbolDMContext symCtx, GetDataDone<Iterable<ISymbolObjectDMContext>> done);
}

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.service;
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.IDMData;
import org.eclipse.dd.dsf.datamodel.IDMEvent;
import org.eclipse.dd.dsf.datamodel.IDMService;
/**
* This is just an initial take at the targets interface.
*/
public interface ITargets extends IDMService {
public interface ITargetDMContext extends IDMContext<ITargetDMData> {}
public interface ITargetDMData extends IDMData {
String getName();
boolean isConnected();
}
public interface ITargetStateChanged extends IDMEvent {}
public interface ICoreDMContext extends IDMContext<ICoreDMData> {}
public interface ICoreDMData extends IDMData {
String getName();
boolean isConnected();
IOS.IOSDMContext getOSDMContext();
}
public interface ICoreStateChangedDMEvent extends IDMEvent {}
public void getTargets(GetDataDone<ITargetDMContext> done);
public void getCores(ITargetDMContext target, GetDataDone<ICoreDMContext> done);
public void connectTarget(ITargetDMContext targetDmc, Done done);
public void disconnectTarget(ITargetDMContext targetDmc, Done done);
public void connectCore(ITargetDMContext targetDmc, Done done);
public void disconnectCore(ITargetDMContext targetDmc, Done done);
}

View file

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

View file

@ -1,232 +0,0 @@
/*******************************************************************************
* 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.ui.model;
import org.eclipse.dd.dsf.concurrent.Done;
import org.eclipse.dd.dsf.concurrent.DoneTracker;
import org.eclipse.dd.dsf.concurrent.DsfExecutor;
import org.eclipse.dd.dsf.concurrent.GetDataDone;
import org.eclipse.dd.dsf.concurrent.Immutable;
import org.eclipse.dd.dsf.model.DMCs;
import org.eclipse.dd.dsf.model.IDataModelContext;
import org.eclipse.dd.dsf.model.IDataModelEvent;
import org.eclipse.dd.dsf.service.DsfServicesTracker;
import org.eclipse.dd.dsf.service.DsfSession;
import org.eclipse.dd.dsf.ui.DsfUIPlugin;
import org.eclipse.debug.internal.ui.viewers.provisional.IModelDelta;
/**
* View Model Schema Node based on a single Data Model Context (DMC) type.
* The assumption in this implementation is that elements of this node have
* a single IDataModelContext associated with them, and all of these DMCs
* are of the same class type.
*/
@SuppressWarnings("restriction")
abstract public class DataViewModelSchemaNode implements IViewModelSchemaNode {
/**
* IViewModelContext implementation used for this schema node.
*/
@Immutable
public class DataVMC implements IViewModelContext {
private final IViewModelContext fParent;
private final IDataModelContext fDmc;
public DataVMC(IViewModelContext parent, IDataModelContext dataModelContext) {
fParent = parent;
fDmc = dataModelContext;
}
public IDataModelContext getDataModelContext() { return fDmc; }
public IViewModelContext getParent() { return fParent; }
public IViewModelSchemaNode getSchemaNode() { return DataViewModelSchemaNode.this; }
public Object getAdapter(Class adapter) {
return fDmc.getAdapter(adapter);
}
public boolean equals(Object other) {
if (!(other instanceof DataVMC)) return false;
DataVMC otherVmc = (DataVMC)other;
return DataViewModelSchemaNode.this.equals(otherVmc.getSchemaNode()) &&
fParent.equals(otherVmc.fParent) &&
fDmc.equals(otherVmc.fDmc);
}
public int hashCode() {
return DataViewModelSchemaNode.this.hashCode() + fParent.hashCode() + fDmc.hashCode();
}
public String toString() {
return fParent.toString() + "->" + fDmc.toString();
}
}
/** Executor to use when posting done tokens. */
private DsfExecutor fExecutor;
/** Service tracker to be used by sub-classes */
private DsfServicesTracker fServices;
/** Child schema nodes of this node. */
private IViewModelSchemaNode[] fChildNodes = new IViewModelSchemaNode[0];
/** Class type that the elements of this schema node are based on. */
private Class<? extends IDataModelContext> fDMCClassType;
/**
* Constructor initializes instance data, except for the child nodes.
* Child nodes must be initialized by calling setChildNodes()
* @param session
* @param dmcClassType
* @see #setChildNodes(IViewModelSchemaNode[])
*/
public DataViewModelSchemaNode(DsfSession session, Class<? extends IDataModelContext> dmcClassType) {
fServices = new DsfServicesTracker(DsfUIPlugin.getBundleContext(), session.getId());
fExecutor = session.getExecutor();
fDMCClassType = dmcClassType;
}
/**
* Sets the child schema nodes of this node. Needs to be configured
* before the schema node is used.
*/
public void setChildNodes(IViewModelSchemaNode[] childNodes) {
fChildNodes = childNodes;
}
public IViewModelSchemaNode[] getChildNodes() {
return fChildNodes;
}
/**
* If any of the children nodes have delta flags, that means that this
* node has to generate a delta as well.
*/
public boolean hasDeltaFlags(IDataModelEvent e) {
for (IViewModelSchemaNode childNode : getChildNodes()) {
if (childNode.hasDeltaFlags(e)) return true;
}
return false;
}
/**
* Handles calling child schema nodes to build the model delta. If child
* schema nodes have deltas, this schema node has to provide the
* IModelDelta objects that the child shema node can build on.
*/
public void buildDelta(final IDataModelEvent e, final ViewModelDelta parent, final Done done) {
DoneTracker childNodesDoneTracker = new DoneTracker() { public void run() {
fExecutor.execute(done);
}};
// Note: this is pretty inefficient. For one the below loop could
// potentially retrieve the elements for this node several times, but
// beyond that it may be possible to optimize this code based on what's
// visible in the view.
for (final IViewModelSchemaNode childNode : getChildNodes()) {
if (childNode.hasDeltaFlags(e)) {
// Take the IDataModelContext (DMC) that the event is based on,
// and search its ancestors. Look for the DMC class typs that
// this schema node is based on. If its found, then only one
// IModelDelta needs to be generated for this schema node.
// Otherwise, a IModelDelta needs to be created for every
// element in this schema node. And for every element from
// this node, the child schema node needs to be called.
final Done childNodeDone = childNodesDoneTracker.addNoActionDone();
IDataModelContext dmc = DMCs.getAncestorOfType(e.getDMC(), fDMCClassType);
if (dmc != null) {
childNode.buildDelta(
e,
parent.addNode(new DataVMC(parent.getVMC(), dmc), IModelDelta.NO_CHANGE),
childNodeDone);
} else {
getElements(
parent.getVMC(),
new GetDataDone<IViewModelContext[]>() { public void run() {
if (!getStatus().isOK()) {
fExecutor.execute(done);
return;
} else {
// For each element in this schema node, create
// a separate IModelDelta, and call the child
// schema node with it.
final DoneTracker doneTracker = new DoneTracker() { public void run() {
fExecutor.execute(childNodeDone);
}};
for (IViewModelContext element : getData()) {
childNode.buildDelta(
e,
parent.addNode(element, IModelDelta.NO_CHANGE),
doneTracker.addNoActionDone());
}
}
}});
}
}
}
// Check if there was anything to be done. If not, invoke the client
// done.
if (childNodesDoneTracker.getDones().isEmpty()) {
fExecutor.execute(done);
}
}
/**
* Returns the services tracker for sub-class use.
*/
protected DsfServicesTracker getServicesTracker() {
return fServices;
}
/**
* Returns the executor for sub-class use.
*/
protected DsfExecutor getExecutor() {
return fExecutor;
}
/**
* Utility method that takes an array of DMC object and creates a
* corresponding array of IViewModelContext elements base on that.
* @param parent The parent for generated IViewModelContext elements.
* @param dmContexts Array of DMC objects to build return array on.
* @return Array of IViewModelContext objects.
*/
protected IViewModelContext[] wrapDMContexts(IViewModelContext parent, IDataModelContext[] dmContexts) {
IViewModelContext[] vmContexts = new IViewModelContext[dmContexts.length];
for (int i = 0; i < dmContexts.length; i++) {
vmContexts[i] = new DataVMC(parent, dmContexts[i]);
}
return vmContexts;
}
@SuppressWarnings("unchecked")
public static <V extends IDataModelContext> V findDMContext(IViewModelContext vmc, Class<V> dmcType) {
if (vmc instanceof DataViewModelSchemaNode.DataVMC &&
dmcType.isAssignableFrom( ((DataViewModelSchemaNode.DataVMC)vmc).getDataModelContext().getClass() ))
{
return (V)((DataViewModelSchemaNode.DataVMC)vmc).getDataModelContext();
} else if (vmc.getParent() != null) {
return findDMContext(vmc.getParent(), dmcType);
}
return null;
}
public void sessionDispose() {
fServices.dispose();
for (IViewModelSchemaNode childNode : getChildNodes()) {
childNode.sessionDispose();
}
}
}

View file

@ -1,271 +0,0 @@
/*******************************************************************************
* 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.ui.model;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.jobs.ISchedulingRule;
import org.eclipse.core.runtime.jobs.Job;
import org.eclipse.dd.dsf.concurrent.ConfinedToDsfExecutor;
import org.eclipse.dd.dsf.concurrent.Done;
import org.eclipse.dd.dsf.concurrent.DoneTracker;
import org.eclipse.dd.dsf.concurrent.GetDataDone;
import org.eclipse.dd.dsf.concurrent.ThreadSafe;
import org.eclipse.dd.dsf.model.IDataModelEvent;
import org.eclipse.dd.dsf.service.DsfSession;
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.IContainerRequestMonitor;
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.IModelProxy;
/**
* View model provider implements the asynchronous view model functionality for
* a single view. This provider is just a holder which further delegates the
* model provider functionality to the view model schema nodes that need
* to be configured with each provider.
* <p>
* The view model provider, often does not provide the model for the entire
* view. Rather, it needs to be able to plug in at any level in the viewer's
* content model and provide data for a sub-tree.
*
* @see IAsynchronousContentAdapter
* @see IAsynchronousLabelAdapter
* @see IModelProxy
* @see IViewModelSchemaNode
*/
@ConfinedToDsfExecutor("fSession#getExecutor")
@SuppressWarnings("restriction")
public class ViewModelProvider extends AbstractModelProxy
{
private final DsfSession fSession;
/**
* 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;
/**
* Schema nodes that define the contents of this view model.
* They must be initialized with setRootSchemaNodes() before using the
* model provider.
*/
private IViewModelSchemaNode[] fRootSchemaNodes = new IViewModelSchemaNode[0];
/**
* Root VMC node for the model. The devault value may be overriden with
* an object from a tree, by the data model adapter.
*/
IViewModelContext fRootVMC = new IViewModelContext(){
public IViewModelContext getParent() { return null; }
public IViewModelSchemaNode getSchemaNode() { return null; }
public Object getAdapter(Class adapter) {
return fSession.getModelAdapter(adapter);
}
public String toString() {
return "Root";
}
};
/**
* Constructs the view model provider for given DSF session.
*/
public ViewModelProvider(DsfSession session) {
fSession = session;
fRootSchemaNodes = new IViewModelSchemaNode[0];
}
/** Sets the schema nodes */
public void setRootSchemaNodes(IViewModelSchemaNode[] rootSchemaNodes) {
for (IViewModelSchemaNode node : fRootSchemaNodes) {
node.sessionDispose();
}
fRootSchemaNodes = rootSchemaNodes;
}
/** Sets the root element */
public void setRootElement(IViewModelContext vmc) {
fRootVMC = vmc;
}
/** Retrieves the root element */
public IViewModelContext getRootElement() { return fRootVMC; }
/** Called to dispose the provider. */
public void sessionDispose() {
for (IViewModelSchemaNode node : fRootSchemaNodes) {
node.sessionDispose();
}
}
private boolean isOurSchemaNode(IViewModelSchemaNode schemaNode, IViewModelSchemaNode[] nodesToSearch) {
for (IViewModelSchemaNode node : nodesToSearch) {
if (node == schemaNode) return true;
if (isOurSchemaNode(schemaNode, node.getChildNodes())) return true;
}
return false;
}
/**
* Performs the query to determine if given VNC is a container.
* Note: this method must be called on the provider's dispatch thread.
* @see IAsynchronousContentAdapter#isContainer(Object, org.eclipse.debug.internal.ui.viewers.provisional.IPresentationContext, IContainerRequestMonitor)
*/
@SuppressWarnings("unchecked")
public void isContainer(IViewModelContext vmc, final IContainerRequestMonitor monitor)
{
assert fSession.getExecutor().isInExecutorThread();
// If the VMC is the root element, use the root schema nodes to
// collect the list of children. Otherwise, get the child schema nodes
// out of VMC's schema node.
IViewModelSchemaNode[] childSchemaNodes;
if (vmc == fRootVMC || !isOurSchemaNode(vmc.getSchemaNode(), fRootSchemaNodes)) {
childSchemaNodes = fRootSchemaNodes;
} else {
childSchemaNodes = vmc.getSchemaNode().getChildNodes();
}
// For each child schema node, retrieve the list of elements. When
// all are done, notify the request monitor.
final DoneTracker doneTracker = new DoneTracker() {
public void run() {
boolean isContainer = false;
for (Done hasElementsDone : getDones().keySet()) {
isContainer |= hasElementsDone.getStatus().isOK() &&
((GetDataDone<Boolean>)hasElementsDone).getData().booleanValue();
}
monitor.setIsContainer(isContainer);
monitor.done();
}};
for (IViewModelSchemaNode childNode : childSchemaNodes) {
childNode.hasElements(
vmc,
doneTracker.add( new GetDataDone<Boolean>() { public void run() {
doneTracker.doneDone(this);
}}));
}
}
/**
* Performs the query to retrieve children for the given VMC.
* Note: this method must be called on the provider's dispatch thread.
* @see IAsynchronousContentAdapter#retrieveChildren(Object, org.eclipse.debug.internal.ui.viewers.provisional.IPresentationContext, IChildrenRequestMonitor)
*/
@SuppressWarnings("unchecked")
public void retrieveChildren(final IViewModelContext vmc, final IChildrenRequestMonitor monitor)
{
assert fSession.getExecutor().isInExecutorThread();
// Get the child nodes as in isContainer().
IViewModelSchemaNode[] childSchemaNodes;
if (vmc == fRootVMC || !isOurSchemaNode(vmc.getSchemaNode(), fRootSchemaNodes)) {
childSchemaNodes = fRootSchemaNodes;
} else {
childSchemaNodes = vmc.getSchemaNode().getChildNodes();
}
// Collect the elements from each child schema node.
final DoneTracker doneTracker = new DoneTracker() { public void run() {
monitor.done();
}};
for (IViewModelSchemaNode childNode : childSchemaNodes) {
childNode.getElements(
vmc,
doneTracker.add( new GetDataDone<IViewModelContext[]>() { public void run() {
if (getStatus().isOK()) {
monitor.addChildren(getData());
}
doneTracker.doneDone(this);
}}));
}
}
/**
* 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(IViewModelContext vmc, final ILabelRequestMonitor result)
{
assert fSession.getExecutor().isInExecutorThread();
vmc.getSchemaNode().retrieveLabel(vmc, result);
}
///////////////////////////////////////////////////////////////////////////
// IModelProxy
private ISchedulingRule fModelChangeRule = new ISchedulingRule() {
public boolean contains(ISchedulingRule rule) { return this == rule; }
public boolean isConflicting(ISchedulingRule rule) { return rule == this; }
};
@ThreadSafe
public void installed() {
fProxyActive++;
}
@ThreadSafe
public void dispose() {
fProxyActive--;
super.dispose();
}
/**
* Called by the async. data model adapter, this method generates and
* dispatches the view model delta for the given data model event.
* Note: the root node in the delta must be supplied to the view model
* provider, because the root view model provider node may not be at the
* root of the viewer's tree.
* @param rootDeltaNode Root node to use for additional delta.
* @param e Data model event received.
*/
public void handleDataModelEvent(final ViewModelDelta rootDeltaNode, IDataModelEvent e) {
// Go through all the schema nodes and collect delta information for
// the received event.
DoneTracker doneTracker = new DoneTracker() { public void run() {
if (rootDeltaNode.getFlags() != IModelDelta.NO_CHANGE || rootDeltaNode.getNodes().length != 0) {
// Fire the delta only if there are changes.
fireModelChangedNonDispatch(rootDeltaNode);
}
}};
for (final IViewModelSchemaNode childNode : fRootSchemaNodes) {
if (childNode.hasDeltaFlags(e)) {
childNode.buildDelta(e, rootDeltaNode, doneTracker.addNoActionDone());
}
}
}
/**
* Fires given delta using a job. Processing the delta on the dispatch
* thread can lead to dead-locks.
* @param delta
*/
private void fireModelChangedNonDispatch(final IModelDelta delta) {
if (fProxyActive <= 0) return;
Job job = new Job("Computing isContainer") { //$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

@ -0,0 +1,164 @@
/*******************************************************************************
* 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.ui.viewmodel;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.RejectedExecutionException;
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.DsfRunnable;
import org.eclipse.dd.dsf.concurrent.ThreadSafe;
import org.eclipse.dd.dsf.service.DsfSession;
import org.eclipse.dd.dsf.service.IDsfService;
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.IContainerRequestMonitor;
import org.eclipse.debug.internal.ui.viewers.provisional.ILabelRequestMonitor;
import org.eclipse.debug.internal.ui.viewers.provisional.IModelProxy;
import org.eclipse.debug.internal.ui.viewers.provisional.IModelProxyFactoryAdapter;
import org.eclipse.debug.internal.ui.viewers.provisional.IPresentationContext;
/**
* Base implementation for DSF-based view model adapters.
*/
@ThreadSafe
@SuppressWarnings("restriction")
abstract public class AbstractVMAdapter
implements IAsynchronousLabelAdapter,
IAsynchronousContentAdapter,
IModelProxyFactoryAdapter
{
private final DsfSession fSession;
@ConfinedToDsfExecutor("getSession().getExecutor()")
private Map<IPresentationContext, VMProvider> fViewModelProviders =
new HashMap<IPresentationContext, VMProvider>();
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()")
abstract protected VMProvider createViewModelProvider(IPresentationContext context);
protected DsfSession getSession() { return fSession; }
@ConfinedToDsfExecutor("getSession().getExecutor()")
private VMProvider getViewModelProvider(IPresentationContext context) {
VMProvider provider = fViewModelProviders.get(context);
if (provider == null) {
provider = createViewModelProvider(context);
if (provider != null) {
fViewModelProviders.put(context, provider);
}
}
return provider;
}
@ConfinedToDsfExecutor("getSession().getExecutor()")
public void install(IPresentationContext context) {
}
@ConfinedToDsfExecutor("getSession().getExecutor()")
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();
}
fViewModelProviders.clear();
}
public void retrieveLabel(final Object object, final IPresentationContext context, final ILabelRequestMonitor result) {
try {
getSession().getExecutor().execute(new DsfRunnable() {
public void run() {
if (result.isCanceled()) return;
VMProvider provider = getViewModelProvider(context);
if (provider == null) {
result.setStatus(new Status(IStatus.ERROR, DsfUIPlugin.PLUGIN_ID, IDsfService.INTERNAL_ERROR, "No model provider for object: " + object.toString(), null));
result.done();
}
provider.retrieveLabel(object, result);
}
@Override
public String toString() { return "Switch to dispatch thread to execute retrieveLabel()"; }
});
} catch(RejectedExecutionException e) {
// This can happen if session is being shut down.
result.done();
}
}
public void isContainer(final Object element, final IPresentationContext context, final IContainerRequestMonitor result) {
try {
getSession().getExecutor().execute(new DsfRunnable() {
public void run() {
if (result.isCanceled()) return;
VMProvider provider = getViewModelProvider(context);
if (provider == null) {
result.setStatus(new Status(IStatus.ERROR, DsfUIPlugin.PLUGIN_ID, IDsfService.INTERNAL_ERROR, "No model provider for object: " + element.toString(), null));
result.done();
}
provider.isContainer(element, result);
}
public String toString() { return "Switch to dispatch thread to execute isContainer()"; }
});
} catch(RejectedExecutionException e) {
// This can happen if session is being shut down.
result.done();
}
}
public void retrieveChildren(final Object element, final IPresentationContext context, final IChildrenRequestMonitor result) {
try {
getSession().getExecutor().execute(new DsfRunnable() {
public void run() {
if (result.isCanceled()) return;
VMProvider provider = getViewModelProvider(context);
if (provider == null) {
result.setStatus(new Status(IStatus.ERROR, DsfUIPlugin.PLUGIN_ID, IDsfService.INTERNAL_ERROR, "No model provider for object: " + element.toString(), null));
result.done();
}
provider.retrieveChildren(element, result);
}
public String toString() { return "Switch to dispatch thread to execute retrieveChildren()"; }
});
} catch(RejectedExecutionException e) {
// This can happen if session is being shut down.
result.done();
}
}
public IModelProxy createModelProxy(Object element, IPresentationContext context) {
VMProvider provider = getViewModelProvider(context);
if (provider != null) {
return provider.getModelProxy();
}
return null;
}
}

View file

@ -0,0 +1,160 @@
/*******************************************************************************
* 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.ui.viewmodel;
import java.util.ArrayList;
import java.util.List;
import org.eclipse.dd.dsf.concurrent.Done;
import org.eclipse.dd.dsf.concurrent.DoneCollector;
import org.eclipse.dd.dsf.concurrent.DsfExecutor;
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;
/**
*
*/
@SuppressWarnings("restriction")
abstract public class AbstractVMLayoutNode implements IVMLayoutNode {
private final DsfExecutor fExecutor;
/** Child schema nodes of this node. */
private IVMLayoutNode[] fChildNodes = new IVMLayoutNode[0];
public AbstractVMLayoutNode(DsfExecutor executor) {
fExecutor = executor;
}
/**
* Accessor method for sub-classes.
*/
protected DsfExecutor getExecutor() {
return fExecutor;
}
public void setChildNodes(IVMLayoutNode[] childNodes) {
fChildNodes = childNodes;
}
public IVMLayoutNode[] getChildLayoutNodes() {
return fChildNodes;
}
public void sessionDispose() {
for (IVMLayoutNode childNode : getChildLayoutNodes()) {
childNode.sessionDispose();
}
}
/**
* If any of the children nodes have delta flags, that means that this
* node has to generate a delta as well.
*/
public boolean hasDeltaFlags(Object e) {
for (IVMLayoutNode childNode : getChildLayoutNodes()) {
if (childNode.hasDeltaFlags(e)) return true;
}
return false;
}
/**
* Handles calling child schema nodes to build the model delta. If child
* schema nodes have deltas, this schema node has to provide the
* IModelDelta objects that the child shema node can build on.
*/
public void buildDelta(final Object e, final VMDelta parent, final Done done) {
/*
* Find the child nodes that have deltas for the given event. If no
* child layout nodes have deltas, just invoke the done.
*/
final IVMLayoutNode[] childNodes = getChildNodesWithDeltas(e);
if (childNodes.length == 0) {
getExecutor().execute(done);
return;
}
/*
* The given child layout nodes have deltas potentially for all elements
* from this node. Retrieve all elements and call the child nodes with
* each element as the parent of their delta.
*/
getElements(
parent.getVMC(),
new GetDataDone<IVMContext[]>() {
public void run() {
if (propagateError(getExecutor(), done, "Failed to retrieve elements in layout node " + AbstractVMLayoutNode.this)) return;
/*
* The execution for this node is not done until all the child nodes
* are done. Use the tracker to wait for all children to complete.
*/
final DoneCollector doneCollector = new DoneCollector(getExecutor()) { public void run() {
getExecutor().execute(done);
}};
for (IVMContext element : getData()) {
for (final IVMLayoutNode childNode : childNodes) {
childNode.buildDelta(
e,
parent.addNode(element, IModelDelta.NO_CHANGE),
doneCollector.addNoActionDone());
}
}
}
});
}
/**
* Convenience method that returns the child layout nodes which return
* <code>true</code> to the <code>hasDeltaFlags()</code> test for the given
* event.
*/
protected IVMLayoutNode[] getChildNodesWithDeltas(Object e) {
List<IVMLayoutNode> nodes = new ArrayList<IVMLayoutNode>();
for (final IVMLayoutNode childNode : getChildLayoutNodes()) {
if (childNode.hasDeltaFlags(e)) {
nodes.add(childNode);
}
}
return nodes.toArray(new IVMLayoutNode[nodes.size()]);
}
/**
* Convenience method that returns a token value in case when the services
* that the layout node depends on, are not available.
*/
protected void handleFailedHasElements(GetDataDone<Boolean> done) {
done.setData(false);
getExecutor().execute(done);
}
/**
* Convenience method that returns a token value in case when the services
* that the layout node depends on, are not available.
*/
protected void handleFailedGetElements(GetDataDone<IVMContext[]> done) {
done.setData(new IVMContext[0]);
getExecutor().execute(done);
}
/**
* Convenience method that returns a token value in case when the services
* that the layout node depends on, are not available.
*/
protected void handleFailedRetrieveLabel(ILabelRequestMonitor result) {
result.setLabels(new String[] { "..."} );
result.done();
}
}

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.ui.viewmodel;
import org.eclipse.core.runtime.IAdaptable;
import org.eclipse.dd.dsf.concurrent.DoneCollector;
import org.eclipse.dd.dsf.concurrent.DsfExecutor;
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;
/**
*
*/
@SuppressWarnings("restriction")
abstract public class AbstractVMRootLayoutNode extends AbstractVMLayoutNode implements IVMRootLayoutNode {
protected static class RootVMC<V> implements IRootVMC {
private final V fInputObject;
private final IVMRootLayoutNode fVMRootLayoutNode;
public RootVMC(IVMRootLayoutNode vmRootLayoutNode, V inputObject) {
fVMRootLayoutNode = vmRootLayoutNode;
fInputObject = inputObject;
}
/** Returns the ILaunch object belonging to this launch VMC. */
public V getInputObject() { return fInputObject; }
public IVMContext getParent() { return null; }
public IVMLayoutNode getLayoutNode() { return fVMRootLayoutNode; }
public Object getAdapter(Class adapter) {
if (fInputObject instanceof IAdaptable) {
return ((IAdaptable)fInputObject).getAdapter(adapter);
}
return null;
}
public boolean equals(Object other) {
return getClass().equals( other.getClass() ) &&
fInputObject.equals( ((RootVMC)other).getInputObject() );
}
public int hashCode() {
return fInputObject.hashCode();
}
public String toString() { return "Root VMC for " + fInputObject.toString(); }
}
public AbstractVMRootLayoutNode(DsfExecutor executor) {
super(executor);
}
/**
* This implementation only fulfils the requirements of the super-interface.
* 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 getElements(IVMContext parentVmc, GetDataDone<IVMContext[]> done) {
done.setData(new IVMContext[] { getRootVMC() });
getExecutor().execute(done);
}
/**
* This implementation only fulfils the requirements of the super-interface.
* 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 hasElements(IVMContext parentVmc, GetDataDone<Boolean> done) {
done.setData(true);
getExecutor().execute(done);
}
/**
* This implementation only fulfils the requirements of the super-interface.
* 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) {
result.done();
}
/**
* Default implementation creates a delta assuming that the root layout node
* is the input object into the view.
*/
public void createDelta(Object event, final GetDataDone<IModelDelta> done) {
final VMDelta rootDelta = new VMDelta(getRootVMC().getInputObject(), getRootVMC());
final IVMLayoutNode[] childNodes = getChildNodesWithDeltas(event);
if (childNodes.length == 0) {
done.setData(rootDelta);
getExecutor().execute(done);
return;
}
/*
* The execution for this node is not done until all the child nodes
* are done. Use the tracker to wait for all children to complete.
*/
final DoneCollector doneCollector = new DoneCollector(getExecutor()) {
public void run() {
if (propagateError(getExecutor(), done, "Failed to generate child deltas.")) return;
done.setData(rootDelta);
getExecutor().execute(done);
}
};
for (final IVMLayoutNode childNode : childNodes) {
childNode.buildDelta(event, rootDelta, doneCollector.addNoActionDone());
}
}
}

View file

@ -0,0 +1,222 @@
/*******************************************************************************
* 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.ui.viewmodel;
import org.eclipse.dd.dsf.concurrent.Done;
import org.eclipse.dd.dsf.concurrent.DoneCollector;
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.IDMEvent;
import org.eclipse.dd.dsf.service.DsfServicesTracker;
import org.eclipse.dd.dsf.service.DsfSession;
import org.eclipse.dd.dsf.ui.DsfUIPlugin;
import org.eclipse.dd.dsf.ui.viewmodel.IVMRootLayoutNode.IRootVMC;
import org.eclipse.debug.internal.ui.viewers.provisional.IModelDelta;
/**
* View model layout node based on a single Data Model Context type.
* The assumption in this implementation is that elements of this node have
* a single IDMContext associated with them, and all of these contexts
* are of the same class type.
*/
@SuppressWarnings("restriction")
abstract public class DMContextVMLayoutNode extends AbstractVMLayoutNode {
/**
* IVMContext implementation used for this schema node.
*/
@Immutable
public class DMContextVMContext implements IVMContext {
private final IVMContext fParent;
private final IDMContext fDmc;
public DMContextVMContext(IVMContext parent, IDMContext dmc) {
fParent = parent;
fDmc = dmc;
}
public IDMContext getDMC() { return fDmc; }
public IVMContext getParent() { return fParent; }
public IVMLayoutNode getLayoutNode() { return DMContextVMLayoutNode.this; }
public Object getAdapter(Class adapter) {
return fDmc.getAdapter(adapter);
}
public boolean equals(Object other) {
if (!(other instanceof DMContextVMContext)) return false;
DMContextVMContext otherVmc = (DMContextVMContext)other;
return DMContextVMLayoutNode.this.equals(otherVmc.getLayoutNode()) &&
fParent.equals(otherVmc.fParent) &&
fDmc.equals(otherVmc.fDmc);
}
public int hashCode() {
return DMContextVMLayoutNode.this.hashCode() + fParent.hashCode() + fDmc.hashCode();
}
public String toString() {
return fParent.toString() + "->" + fDmc.toString();
}
}
/** Service tracker to be used by sub-classes */
private DsfServicesTracker fServices;
/** Class type that the elements of this schema node are based on. */
private Class<? extends IDMContext> fDMCClassType;
/**
* Constructor initializes instance data, except for the child nodes.
* Child nodes must be initialized by calling setChildNodes()
* @param session
* @param dmcClassType
* @see #setChildNodes(IVMLayoutNode[])
*/
public DMContextVMLayoutNode(DsfSession session, Class<? extends IDMContext> dmcClassType) {
super(session.getExecutor());
fServices = new DsfServicesTracker(DsfUIPlugin.getBundleContext(), session.getId());
fDMCClassType = dmcClassType;
}
/**
* Returns the services tracker for sub-class use.
*/
protected DsfServicesTracker getServicesTracker() {
return fServices;
}
@Override
public boolean hasDeltaFlags(Object e) {
if (e instanceof IDMEvent) {
return hasDeltaFlagsForDMEvent((IDMEvent)e);
} else {
return super.hasDeltaFlags(e);
}
}
/**
* DMC-specific version of {@link IVMLayoutNode#hasDeltaFlags(Object)}.
* By default, it falls back on the super-class implementation.
*/
protected boolean hasDeltaFlagsForDMEvent(IDMEvent e) {
return super.hasDeltaFlags(e);
}
@Override
public void buildDelta(Object e, VMDelta parent, Done done) {
if (e instanceof IDMEvent) {
buildDeltaForDMEvent((IDMEvent)e, parent, done);
} else {
super.buildDelta(e, parent, done);
}
}
/**
* Adds an optimization (over the AbstractViewModelLayoutNode) which
* narrows down the list of children based on the DMC within the event.
*/
public void buildDeltaForDMEvent(final IDMEvent e, final VMDelta parent, final Done done) {
/*
* Take the IDMContext (DMC) that the event is based on, and
* search its ancestors. Look for the DMC class typs that this schema
* node is based on. If its found, then only one IModelDelta needs to
* be generated for this schema node. Otherwise, resort to the default
* behavior and generate a IModelDelta for every element in this schema
* node.
*/
IDMContext dmc = DMContexts.getAncestorOfType(e.getDMContext(), fDMCClassType);
if (dmc != null) {
IVMLayoutNode[] childNodes = getChildNodesWithDeltas(e);
if (childNodes.length == 0) {
// There are no child nodes with deltas, just return to parent.
getExecutor().execute(done);
return;
}
/*
* This execution for this node is not done until all the child nodes
* are done. Use the tracker to wait for all children to complete.
*/
DoneCollector childDoneTracker = new DoneCollector(getExecutor()) {
public void run() {
getExecutor().execute(done);
}
};
for (final IVMLayoutNode childNode : getChildLayoutNodes()) {
/*
* Create a delta corresponding to the DMC from the event and pass
* it as parent VMC to the child node. The child node will build
* its delta on top of this delta.
*/
childNode.buildDelta(
e,
parent.addNode(new DMContextVMContext(parent.getVMC(), dmc), IModelDelta.NO_CHANGE),
childDoneTracker.addNoActionDone());
}
} else {
super.buildDelta(e, parent, done);
}
}
/**
* Utility method that takes an array of DMC object and creates a
* corresponding array of IVMContext elements base on that.
* @param parent The parent for generated IVMContext elements.
* @param dmcs Array of DMC objects to build return array on.
* @return Array of IVMContext objects.
*/
protected IVMContext[] dmcs2vmcs(IVMContext parent, IDMContext[] dmcs) {
IVMContext[] vmContexts = new IVMContext[dmcs.length];
for (int i = 0; i < dmcs.length; i++) {
vmContexts[i] = new DMContextVMContext(parent, dmcs[i]);
}
return vmContexts;
}
/**
* Searches for a DMC of given type in the tree patch contained in given
* VMC. VMCs keep a reference to the parent node that contain them in the
* tree. This method recursively looks compares the parent until root is
* reached, or the DMC is found. If the root is reached, and the root's
* input is also a VMC (which comes from another view), then the hierarchy
* of the input object will be searched as well.
* @param <V> Type of the DMC that will be returned.
* @param vmc VMC element to search.
* @param dmcType Class object for matching the type.
* @return DMC, or null if not found.
*/
@SuppressWarnings("unchecked")
public static <V extends IDMContext> V findDmcInVmc(IVMContext vmc, Class<V> dmcType) {
if (vmc instanceof IRootVMC && ((IRootVMC)vmc).getInputObject() instanceof IVMContext) {
vmc = (IVMContext)((IRootVMC)vmc).getInputObject();
}
if (vmc instanceof DMContextVMLayoutNode.DMContextVMContext &&
dmcType.isAssignableFrom( ((DMContextVMLayoutNode.DMContextVMContext)vmc).getDMC().getClass() ))
{
return (V)((DMContextVMLayoutNode.DMContextVMContext)vmc).getDMC();
} else if (vmc.getParent() != null) {
return findDmcInVmc(vmc.getParent(), dmcType);
}
return null;
}
public void sessionDispose() {
fServices.dispose();
super.sessionDispose();
}
}

View file

@ -8,7 +8,7 @@
* Contributors:
* Wind River Systems - initial API and implementation
*******************************************************************************/
package org.eclipse.dd.dsf.ui.model;
package org.eclipse.dd.dsf.ui.viewmodel;
import org.eclipse.dd.dsf.concurrent.GetDataDone;
import org.eclipse.debug.internal.ui.viewers.provisional.IAsynchronousRequestMonitor;

View file

@ -8,7 +8,7 @@
* Contributors:
* Wind River Systems - initial API and implementation
*******************************************************************************/
package org.eclipse.dd.dsf.ui.model;
package org.eclipse.dd.dsf.ui.viewmodel;
import org.eclipse.core.runtime.IAdaptable;
import org.eclipse.dd.dsf.concurrent.Immutable;
@ -17,16 +17,16 @@ import org.eclipse.dd.dsf.concurrent.Immutable;
* View model element which is stored as the data object of nodes in the viewer.
*/
@Immutable
public interface IViewModelContext extends IAdaptable {
public interface IVMContext extends IAdaptable {
/**
* Returns the schema node that originated this element.
* Returns the layout node that originated this element.
*/
public IViewModelSchemaNode getSchemaNode();
public IVMLayoutNode getLayoutNode();
/**
* Returns the parent of this element in the viewer layout.
* @return
*/
public IViewModelContext getParent();
public IVMContext getParent();
}

View file

@ -8,29 +8,28 @@
* Contributors:
* Wind River Systems - initial API and implementation
*******************************************************************************/
package org.eclipse.dd.dsf.ui.model;
package org.eclipse.dd.dsf.ui.viewmodel;
import org.eclipse.dd.dsf.concurrent.ConfinedToDsfExecutor;
import org.eclipse.dd.dsf.concurrent.Done;
import org.eclipse.dd.dsf.concurrent.GetDataDone;
import org.eclipse.dd.dsf.model.IDataModelEvent;
import org.eclipse.debug.internal.ui.viewers.provisional.ILabelRequestMonitor;
import org.eclipse.debug.internal.ui.viewers.provisional.IModelDelta;
/**
* Schema nodes are combined together into a tree, to collectively define the
* layout of a view. Each schema node generates elements of type
* IViewModelContext, and provide label information about these elements.
* View model layout nodes are combined together into a tree, to collectively
* define the layout of a view. Each schema node generates elements of type
* IVMContext, and provide label information about these elements.
* <p>
* Besides the standard data model context (DMC) based implementation, this
* Besides the standard Data Model Context based implementation, this
* node could be implemented to present data from any source, not necessarily
* DSF services. It could also define a static node which operates on basis
* of other data in the view tree.
* @see ViewModelProvider
* @see VMProvider
*/
@ConfinedToDsfExecutor("")
@SuppressWarnings("restriction")
public interface IViewModelSchemaNode {
public interface IVMLayoutNode {
/**
* Retrieves information whether for the given parent node, there are any elements
@ -39,7 +38,7 @@ public interface IViewModelSchemaNode {
* current level.
* @param done The data return token.
*/
public void hasElements(IViewModelContext parentVmc, GetDataDone<Boolean> done);
public void hasElements(IVMContext parentVmc, GetDataDone<Boolean> done);
/**
* Retrieves the list of elements.
@ -47,39 +46,45 @@ public interface IViewModelSchemaNode {
* current level.
* @param done The data return token.
*/
public void getElements(IViewModelContext parentVmc, GetDataDone<IViewModelContext[]> done);
public void getElements(IVMContext parentVmc, GetDataDone<IVMContext[]> done);
/**
* Retrieves the label for the given element.
* @param vmc Element for which to retrieve label information.
* @param result Monitor which accepts the data.
*/
public void retrieveLabel(IViewModelContext vmc, ILabelRequestMonitor result);
public void retrieveLabel(IVMContext vmc, ILabelRequestMonitor result);
/**
* Returns the list of child schema nodes which are configured for this node.
* Configures the child layout nodes for this node.
* @param childNodes
*/
public IViewModelSchemaNode[] getChildNodes();
public void setChildNodes(IVMLayoutNode[] childNodes);
/**
* Returns the list of child layout nodes which are configured for this node.
*/
public IVMLayoutNode[] getChildLayoutNodes();
/**
* Returns true/false indicating whether the given even will cause this
* schema node to generate a model delta.
* @param e Data model event to process.
* @param event Event to process.
* @return True if this node (or its children) would generate delta data
* due to this event.
* @see IModelDelta
*/
public boolean hasDeltaFlags(IDataModelEvent e);
public boolean hasDeltaFlags(Object event);
/**
* Builds model delta information based on the given event.
* @param e Data model event to process.
* @param event Event to process.
* @param parent Parent model delta node that this object should add delta
* data to.
* @param done Return token, which notifies the caller that the calculation is
* complete.
*/
public void buildDelta(IDataModelEvent e, ViewModelDelta parent, Done done);
public void buildDelta(Object event, VMDelta parent, Done done);
/**
* Disposes the resources held by this node.

View file

@ -0,0 +1,55 @@
/*******************************************************************************
* 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.ui.viewmodel;
import org.eclipse.dd.dsf.concurrent.GetDataDone;
import org.eclipse.debug.internal.ui.viewers.provisional.IModelDelta;
/**
* Special type of the view model layout node, which can be used as a root node
* for a hierarchy. The root node of a layout hierarchy has to implement this
* interface.
*/
@SuppressWarnings("restriction")
public interface IVMRootLayoutNode extends IVMLayoutNode{
/**
* The root VMC object of this root layout node. There can be only element
* in the root node at a time, and this element must implement this
* interface.
*/
public interface IRootVMC extends IVMContext {
/**
* Returns the view's "input" object. This could be the actual input
* object for the whole view, if this view model hierarchy fills the
* whole view. Or this could an element in the tree from which this
* hierarchy starts. This is the case
*/
Object getInputObject();
}
/**
* Returns the single element of this node. Root layout node can only have
* one element, and this is a convenience method to access this element.
* Alternatively getElements() could be used.
* @return
*/
public IRootVMC getRootVMC();
/**
* Version of the {@link IVMLayoutNode#buildDelta(Object, ViewModelDelta, org.eclipse.dd.dsf.concurrent.Done)}
* method, which creates and returns the root node of the delta. It does
* not require a parent object for the delta, as this is the root node.
* @param event Event to process.
* @param done Result notification, contains the root of the delta.
*/
public void createDelta(Object event, GetDataDone<IModelDelta> done);
}

View file

@ -9,7 +9,7 @@
* IBM Corporation - initial API and implementation
* Wind River Systems - adapted to use in DSF
*******************************************************************************/
package org.eclipse.dd.dsf.ui.model;
package org.eclipse.dd.dsf.ui.viewmodel;
import org.eclipse.debug.internal.ui.viewers.provisional.IModelDelta;
import org.eclipse.debug.internal.ui.viewers.provisional.ModelDelta;
@ -22,16 +22,16 @@ import org.eclipse.debug.internal.ui.viewers.provisional.ModelDelta;
* @see IModelDelta#getNodes()
*/
@SuppressWarnings("restriction")
public class ViewModelDelta extends ModelDelta {
public class VMDelta extends ModelDelta {
private ViewModelDelta fParent;
private IViewModelContext fVmcElement;
private VMDelta fParent;
private IVMContext fVmcElement;
private Object fElement;
private int fFlags;
private ViewModelDelta[] fNodes = EMPTY_NODES;
private VMDelta[] fNodes = EMPTY_NODES;
private Object fReplacement;
private int fIndex;
private static final ViewModelDelta[] EMPTY_NODES = new ViewModelDelta[0];
private static final VMDelta[] EMPTY_NODES = new VMDelta[0];
/**
* Constructs a new delta for the given element.
@ -39,7 +39,7 @@ public class ViewModelDelta extends ModelDelta {
* @param vmcElement model element
* @param flags change flags
*/
public ViewModelDelta(IViewModelContext vmcElement, int flags) {
public VMDelta(IVMContext vmcElement, int flags) {
super(vmcElement, flags);
fVmcElement = vmcElement;
fFlags = flags;
@ -53,7 +53,7 @@ public class ViewModelDelta extends ModelDelta {
* @param replacement replacement element
* @param flags change flags
*/
public ViewModelDelta(IViewModelContext vmcElement, Object replacement, int flags) {
public VMDelta(IVMContext vmcElement, Object replacement, int flags) {
super(vmcElement, replacement, flags);
fVmcElement = vmcElement;
fReplacement = replacement;
@ -68,7 +68,7 @@ public class ViewModelDelta extends ModelDelta {
* @param index insertion position
* @param flags change flags
*/
public ViewModelDelta(IViewModelContext vmcElement, int index, int flags) {
public VMDelta(IVMContext vmcElement, int index, int flags) {
super(vmcElement, index, flags);
fVmcElement = vmcElement;
fIndex = index;
@ -83,7 +83,7 @@ public class ViewModelDelta extends ModelDelta {
* @param vmcElement Optional VMC element for this node, it can be used
* by other nodes in the delta to set their VMC parent element correctly.
*/
public ViewModelDelta(Object element, IViewModelContext vmcElement) {
public VMDelta(Object element, IVMContext vmcElement) {
super(element, IModelDelta.NO_CHANGE);
fElement = element;
fVmcElement = vmcElement;
@ -110,7 +110,7 @@ public class ViewModelDelta extends ModelDelta {
fFlags |= flags;
}
public IViewModelContext getVMC() { return fVmcElement; }
public IVMContext getVMC() { return fVmcElement; }
/**
* Adds a child node to this delta with the given element and change flags,
@ -120,8 +120,8 @@ public class ViewModelDelta extends ModelDelta {
* @param flags change flags for child
* @return newly created child delta
*/
public ViewModelDelta addNode(IViewModelContext element, int flags) {
ViewModelDelta node = new ViewModelDelta(element, flags);
public VMDelta addNode(IVMContext element, int flags) {
VMDelta node = new VMDelta(element, flags);
node.setParent(this);
addDelta(node);
return node;
@ -137,8 +137,8 @@ public class ViewModelDelta extends ModelDelta {
* @param flags change flags
* @return newly created child delta
*/
public ViewModelDelta addNode(IViewModelContext element, Object replacement, int flags) {
ViewModelDelta node = new ViewModelDelta(element, replacement, flags);
public VMDelta addNode(IVMContext element, Object replacement, int flags) {
VMDelta node = new VMDelta(element, replacement, flags);
node.setParent(this);
addDelta(node);
return node;
@ -153,8 +153,8 @@ public class ViewModelDelta extends ModelDelta {
* @param flags change flags
* @return newly created child delta
*/
public ViewModelDelta addNode(IViewModelContext element, int index, int flags) {
ViewModelDelta node = new ViewModelDelta(element, index, flags);
public VMDelta addNode(IVMContext element, int index, int flags) {
VMDelta node = new VMDelta(element, index, flags);
node.setParent(this);
addDelta(node);
return node;
@ -169,8 +169,8 @@ public class ViewModelDelta extends ModelDelta {
* by other nodes in the delta to set their VMC parent element correctly.
* @return Returns the added delta node.
*/
public ViewModelDelta addNode(Object element, IViewModelContext vmcElement) {
ViewModelDelta node = new ViewModelDelta(element, vmcElement);
public VMDelta addNode(Object element, IVMContext vmcElement) {
VMDelta node = new VMDelta(element, vmcElement);
node.setParent(this);
addDelta(node);
return node;
@ -181,7 +181,7 @@ public class ViewModelDelta extends ModelDelta {
*
* @param node parent delta
*/
void setParent(ViewModelDelta node) {
void setParent(VMDelta node) {
fParent = node;
}
@ -209,15 +209,15 @@ public class ViewModelDelta extends ModelDelta {
/* (non-Javadoc)
* @see org.eclipse.debug.internal.ui.viewers.IModelDelta#getNodes()
*/
public ViewModelDelta[] getNodes() {
public VMDelta[] getNodes() {
return fNodes;
}
private void addDelta(ViewModelDelta delta) {
private void addDelta(VMDelta delta) {
if (fNodes.length == 0) {
fNodes = new ViewModelDelta[]{delta};
fNodes = new VMDelta[]{delta};
} else {
ViewModelDelta[] nodes = new ViewModelDelta[fNodes.length + 1];
VMDelta[] nodes = new VMDelta[fNodes.length + 1];
System.arraycopy(fNodes, 0, nodes, 0, fNodes.length);
nodes[fNodes.length] = delta;
fNodes = nodes;
@ -232,7 +232,7 @@ public class ViewModelDelta extends ModelDelta {
return buf.toString();
}
private void appendDetail(StringBuffer buf, ViewModelDelta delta) {
private void appendDetail(StringBuffer buf, VMDelta delta) {
buf.append("\tElement: "); //$NON-NLS-1$
buf.append(delta.getElement());
buf.append('\n');
@ -267,7 +267,7 @@ public class ViewModelDelta extends ModelDelta {
}
}
buf.append('\n');
ViewModelDelta[] nodes = delta.getNodes();
VMDelta[] nodes = delta.getNodes();
for (int i = 0; i < nodes.length; i++) {
appendDetail(buf, nodes[i]);
}

View file

@ -0,0 +1,327 @@
/*******************************************************************************
* 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.ui.viewmodel;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.jobs.ISchedulingRule;
import org.eclipse.core.runtime.jobs.Job;
import org.eclipse.dd.dsf.concurrent.ConfinedToDsfExecutor;
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.ThreadSafe;
import org.eclipse.dd.dsf.datamodel.IDMEvent;
import org.eclipse.dd.dsf.service.DsfServiceEventHandler;
import org.eclipse.dd.dsf.service.DsfSession;
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.IContainerRequestMonitor;
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.IModelProxy;
/**
* View model provider implements the asynchronous view model functionality for
* a single view. This provider is just a holder which further delegates the
* model provider functionality to the view model layout nodes that need
* to be configured with each provider.
* <p>
* The view model provider, often does not provide the model for the entire
* view. Rather, it needs to be able to plug in at any level in the viewer's
* content model and provide data for a sub-tree.
*
* @see IAsynchronousContentAdapter
* @see IAsynchronousLabelAdapter
* @see IModelProxy
* @see IVMLayoutNode
*/
@ConfinedToDsfExecutor("fSession#getExecutor")
@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();
}
/**
* 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();
private IVMRootLayoutNode fRootLayoutNode;
/**
* Constructs the view model provider for given DSF session.
*/
public VMProvider(DsfSession session, IVMRootLayoutNode rootLayoutNode) {
fSession = session;
setRootLayoutNode(rootLayoutNode);
// Add ourselves as listener for DM events events.
session.addServiceEventListener(this, null);
}
/** Sets the layout nodes */
public void setRootLayoutNode(IVMRootLayoutNode rootLayoutNode) {
if (fRootLayoutNode != null) {
fRootLayoutNode.sessionDispose();
}
fRootLayoutNode = rootLayoutNode;
}
public IVMRootLayoutNode getRootLayoutNode() {
return fRootLayoutNode;
}
/** Called to dispose the provider. */
public void sessionDispose() {
fSession.removeServiceEventListener(this);
fRootLayoutNode.sessionDispose();
}
protected DsfSession getSession() { return fSession; }
/**
* Performs the query to determine if given VNC is a container.
* Note: this method must be called on the provider's dispatch thread.
* @see IAsynchronousContentAdapter#isContainer(Object, org.eclipse.debug.internal.ui.viewers.provisional.IPresentationContext, IContainerRequestMonitor)
*/
@SuppressWarnings("unchecked")
public void isContainer(Object parent, final IContainerRequestMonitor monitor)
{
assert fSession.getExecutor().isInExecutorThread();
IVMContext parentVmc = getVmcForObject(parent);
if (parentVmc == null) {
monitor.done();
return;
}
/*
* If the element's model node has no child layout nodes, it's not a
* container.
*/
if (parentVmc.getLayoutNode().getChildLayoutNodes().length == 0) {
monitor.setIsContainer(false);
monitor.done();
return;
}
/*
* For each child layout node, retrieve the list of elements. When
* all are done, If any of the child nodes have elements, notify the
* monitor that there are children.
*/
final DoneCollector doneCollector = new DoneCollector(fSession.getExecutor()) {
public void run() {
if (monitor.isCanceled()) return;
boolean isContainer = false;
for (Done hasElementsDone : getDones().keySet()) {
isContainer |= hasElementsDone.getStatus().isOK() &&
((GetDataDone<Boolean>)hasElementsDone).getData().booleanValue();
}
monitor.setIsContainer(isContainer);
monitor.done();
}
};
for (IVMLayoutNode childNode : parentVmc.getLayoutNode().getChildLayoutNodes()) {
childNode.hasElements(
parentVmc,
doneCollector.add( new GetDataDone<Boolean>() { public void run() {
doneCollector.doneDone(this);
}}));
}
}
/**
* Performs the query to retrieve children for the given VMC.
* Note: this method must be called on the provider's dispatch thread.
* @see IAsynchronousContentAdapter#retrieveChildren(Object, org.eclipse.debug.internal.ui.viewers.provisional.IPresentationContext, IChildrenRequestMonitor)
*/
@SuppressWarnings("unchecked")
public void retrieveChildren(final Object parent, final IChildrenRequestMonitor monitor)
{
assert fSession.getExecutor().isInExecutorThread();
IVMContext parentVmc = getVmcForObject(parent);
if (parentVmc == null) {
monitor.done();
return;
}
/*
* If the element's model node has no child layout nodes. There is
* nothing to do, just mark the monitor done.
*/
if (parentVmc.getLayoutNode().getChildLayoutNodes().length == 0) {
assert false : "We should never get here, because isContainer() should have returned false";
monitor.done();
return;
}
/*
* Iterate through the child layout nodes, and request their elements.
* Requests are async, so use a tracker for the results.
*/
final DoneCollector doneCollector = new DoneCollector(fSession.getExecutor()) {
public void run() {
if (monitor.isCanceled()) return;
monitor.done();
}
};
for (IVMLayoutNode childNode : parentVmc.getLayoutNode().getChildLayoutNodes()) {
childNode.getElements(
parentVmc,
doneCollector.add( new GetDataDone<IVMContext[]>() {
public void run() {
if (getStatus().isOK()) {
monitor.addChildren(getData());
}
doneCollector.doneDone(this);
}
}));
}
}
/**
* Convenience method that finds the VMC corresponding to given parent
* argument given to isContainer() or retrieveChildren().
* @param object Object to find the VMC for.
* @return parent VMC, if null it indicates that the object did not originate
* from this view or is stale.
*/
private IVMContext getVmcForObject(Object parent) {
/*
* 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.
*/
if (parent.equals(fRootLayoutNode.getRootVMC().getInputObject())) {
return fRootLayoutNode.getRootVMC();
} else if (parent instanceof IVMContext){
/*
* The parent is a VMC. Check to make sure that the VMC
* originated from a node in this ViewModelProvider. If it didn't
* it is most likely a result of a change in view layout, and this
* request is a stale request. So just ignore it.
*/
if (isOurLayoutNode( ((IVMContext)parent).getLayoutNode(),
new IVMLayoutNode[] { fRootLayoutNode } ))
{
return (IVMContext)parent;
}
}
return null;
}
/**
* Convenience method which checks whether given layout node is a node
* that is configured in this ViewModelProvider. Implementation
* recursively walks the layout hierarchy, and returns true if it finds
* the node.
*/
private boolean isOurLayoutNode(IVMLayoutNode layoutNode, IVMLayoutNode[] nodesToSearch) {
for (IVMLayoutNode node : nodesToSearch) {
if (node == layoutNode) return true;
if (isOurLayoutNode(layoutNode, node.getChildLayoutNodes())) return true;
}
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
* model provider is then responsible for filling-in and sending the delta
* to the viewer.
* @param e
*/
@DsfServiceEventHandler
public void eventDispatched(final IDMEvent event) {
if (fRootLayoutNode.hasDeltaFlags(event)) {
fRootLayoutNode.createDelta(event, new GetDataDone<IModelDelta>() {
public void run() {
if (getStatus().isOK()) {
fModelProxy.fireModelChangedNonDispatch(getData());
}
}
@Override public String toString() {
return "Result of a delta for event: '" + event.toString() + "' in VMP: '" + VMProvider.this + "'";
}
});
}
}
}

View file

@ -22,9 +22,9 @@ views.&nbsp;&nbsp; <br>
<h3>Development Plans</h3>
This package is also a work in progress and it is missing a major
feature.&nbsp;
This feature is to be able to create a complete view schema using a
This feature is to be able to create a complete view layout using a
simple data specification (XML or other format).&nbsp; Still further, a
feature to build on this, should allow users to modify the view schema
feature to build on this, should allow users to modify the view layout
using GUI tools and to apply the modified layout at runtime.<br>
<p><br>
</p>

View file

@ -6,11 +6,9 @@ Bundle-SymbolicName: org.eclipse.dd.dsf
Bundle-Version: 1.0.0
Bundle-Activator: org.eclipse.dd.dsf.DsfPlugin
Bundle-Localization: plugin
Require-Bundle: org.eclipse.core.runtime,
org.eclipse.debug.core
Require-Bundle: org.eclipse.core.runtime
Eclipse-LazyStart: true
Export-Package: org.eclipse.dd.dsf.concurrent,
org.eclipse.dd.dsf.debug,
org.eclipse.dd.dsf.model,
org.eclipse.dd.dsf.datamodel,
org.eclipse.dd.dsf.service
Bundle-RequiredExecutionEnvironment: J2SE-1.5

View file

@ -178,10 +178,16 @@ public class DefaultDsfExecutor extends ScheduledThreadPoolExecutor
// Append executable class name
traceBuilder.append(getExecutable().getClass().getName());
// Add executable's toString().
traceBuilder.append("\n ");
traceBuilder.append(getExecutable().toString());
// Append "create by" info.
if (getExecutable() instanceof DsfExecutable) {
DsfExecutable dsfExecutable = (DsfExecutable)getExecutable();
if (dsfExecutable.fCreatedAt != null || dsfExecutable.fCreatedBy != null) {
traceBuilder.append("\n Created ");
traceBuilder.append("\n created ");
if (dsfExecutable.fCreatedBy != null) {
traceBuilder.append(" by #");
traceBuilder.append(dsfExecutable.fCreatedBy.fSequenceNumber);
@ -194,19 +200,14 @@ public class DefaultDsfExecutor extends ScheduledThreadPoolExecutor
}
// Submitted info
traceBuilder.append("\n ");
traceBuilder.append("Submitted");
traceBuilder.append("\n submitted");
if (fSubmittedBy != null) {
traceBuilder.append(" by #");
traceBuilder.append(fSubmittedBy.fSequenceNumber);
}
traceBuilder.append(" at ");
traceBuilder.append(fSubmittedAt.fStackTraceElements[0].toString());
// Finally, the executable's toString().
traceBuilder.append("\n ");
traceBuilder.append(getExecutable().toString());
// Finally write out to console
DsfPlugin.debug(traceBuilder.toString());
}

View file

@ -66,6 +66,6 @@ abstract public class Done extends DsfRunnable {
}
public String toString() {
return getStatus().toString();
return "Done: " + getStatus().toString();
}
}

View file

@ -17,25 +17,26 @@ import org.eclipse.core.runtime.MultiStatus;
import org.eclipse.dd.dsf.DsfPlugin;
/**
* Utility class to track multiple done (callback) results of commands
* Utility class to collect multiple done (callback) results of commands
* that are initiated simultaneously. The usage is as follows:
* <pre>
* final DoneTracker doneTracker = new DoneTracker() {
* final DoneCollector doneCollector = new DoneCollector() {
* public void run() {
* System.out.println("All complete, errors=" + !getStatus().isOK());
* }
* };
* for (int i = 0; i < 10; i++) {
* service.call(i, doneTracker.addDone(new Done() {
* service.call(i, doneCollector.addDone(new Done() {
* public void run() {
* System.out.println(Integer.toString(i) + " complete");
* doneTracker.doneDone(this);
* doneCollector.doneDone(this);
* }
* }));
* }
* </pre>
*/
public abstract class DoneTracker extends Done {
public abstract class DoneCollector extends Done {
private final DsfExecutor fExecutor;
private Map<Done,Boolean> fDones = new HashMap<Done,Boolean>();
private int fDoneCounter;
@ -46,8 +47,9 @@ public abstract class DoneTracker extends Done {
* execution of the last done, and in the same dispatch loop.
*
*/
public DoneTracker() {
public DoneCollector(DsfExecutor executor) {
setStatus(new MultiStatus(DsfPlugin.PLUGIN_ID, 0, "Collective status for set of sub-operations.", null));
fExecutor = executor;
}
/**
@ -67,13 +69,15 @@ public abstract class DoneTracker extends Done {
/**
* Adds a Done which performs no actions. This is useful if all work
* is performed inside DoneTracker.run().
* is performed inside DoneCollector.run().
* @return Done which is to be passed as an argument to a service method.
*/
public Done addNoActionDone() {
return add(new Done() { public void run() {
doneDone(this);
}});
return add(new Done() {
public void run() {
doneDone(this);
}
});
}
/**
@ -90,9 +94,9 @@ public abstract class DoneTracker extends Done {
fDoneCounter--;
if (fDoneCounter == 0) {
assert !fDones.containsValue(false);
run();
fExecutor.execute(this);
}
}
}
/**
* Returns the map of Done callbacks. Access to this data is provided
@ -101,4 +105,9 @@ public abstract class DoneTracker extends Done {
* @return map of the done callbacks.
*/
public Map<Done,Boolean> getDones() { return fDones; }
@Override
public String toString() {
return "Done Collector: " + getStatus().toString();
}
}

View file

@ -8,7 +8,7 @@
* Contributors:
* Wind River Systems - initial API and implementation
*******************************************************************************/
package org.eclipse.dd.dsf.model;
package org.eclipse.dd.dsf.datamodel;
import org.eclipse.core.runtime.PlatformObject;
import org.eclipse.dd.dsf.concurrent.Immutable;
@ -16,34 +16,34 @@ import org.eclipse.dd.dsf.service.AbstractDsfService;
import org.eclipse.dd.dsf.service.DsfSession;
/**
* Base implementation of the DMC object. Most functionality here is centered
* around comparing DMCs, as this is a critical to make the views work
* correctly.
* @param <V> Data model data that this context is for.
* Base implementation of the IDMContext interface. Most functionality here
* is centered around comparing DMContexts, as this is a critical to make the
* views work correctly.
* @param <V> Data Model data type that this context is for.
*/
@Immutable
public class AbstractDMC<V extends IDataModelData> extends PlatformObject
implements IDataModelContext<V>
public class AbstractDMContext<V extends IDMData> extends PlatformObject
implements IDMContext<V>
{
private final String fSessionId;
private final String fServiceFilter;
private final IDataModelContext[] fParents;
private final IDMContext[] fParents;
/**
* Main constructor provides all data needed to implement the IModelContext
* interface.
*/
public AbstractDMC(String sessionId, String filter, IDataModelContext[] parents) {
public AbstractDMContext(String sessionId, String filter, IDMContext[] parents) {
fSessionId = sessionId;
fServiceFilter = filter;
fParents = parents;
}
/** Convenience constructor */
public AbstractDMC(AbstractDsfService service, IDataModelContext parent) {
public AbstractDMContext(AbstractDsfService service, IDMContext parent) {
this(service.getSession().getId(),
service.getServiceFilter(),
parent == null ? new IDataModelContext[] {} : new IDataModelContext[] { parent });
parent == null ? new IDMContext[] {} : new IDMContext[] { parent });
}
/**
@ -55,13 +55,13 @@ public class AbstractDMC<V extends IDataModelData> extends PlatformObject
protected boolean baseEquals(Object other) {
if (other == null) return false;
if ( !(other.getClass().equals(getClass()))) return false;
IDataModelContext otherCtx = (IDataModelContext)other;
IDMContext otherCtx = (IDMContext)other;
return getSessionId().equals(otherCtx.getSessionId()) &&
getServiceFilter().equals(otherCtx.getServiceFilter()) &&
areParentsEqual(otherCtx.getParents());
}
private boolean areParentsEqual(IDataModelContext[] otherParents) {
private boolean areParentsEqual(IDMContext[] otherParents) {
if ( !(fParents.length == otherParents.length) ) return false;
for (int i = 0; i < fParents.length; i++) {
if (!fParents[i].equals(otherParents[i])) {
@ -81,7 +81,7 @@ public class AbstractDMC<V extends IDataModelData> extends PlatformObject
protected String baseToString() {
StringBuffer retVal = new StringBuffer();
for (IDataModelContext parent : fParents) {
for (IDMContext parent : fParents) {
retVal.append(parent);
}
return retVal.toString();
@ -89,7 +89,7 @@ public class AbstractDMC<V extends IDataModelData> extends PlatformObject
public String getSessionId() { return fSessionId; }
public String getServiceFilter() { return fServiceFilter; }
public IDataModelContext[] getParents() { return fParents; }
public IDMContext[] getParents() { return fParents; }
/**
* Overrides the standard platform getAdapter to provide session-specific

View file

@ -8,22 +8,23 @@
* Contributors:
* Wind River Systems - initial API and implementation
*******************************************************************************/
package org.eclipse.dd.dsf.model;
package org.eclipse.dd.dsf.datamodel;
import org.eclipse.dd.dsf.concurrent.Immutable;
/**
* Base implementation of the IDataModelContext interface.
* Base implementation of the IDMEvent interface. It only handles the
* required DM-Context reference.
*/
@Immutable
public class DataModelEvent<V extends IDataModelContext> implements IDataModelEvent<V> {
public class AbstractDMEvent<V extends IDMContext> implements IDMEvent<V> {
private final V fModelContext;
public DataModelEvent(V context) {
public AbstractDMEvent(V context) {
fModelContext = context;
}
public V getDMC() {
public V getDMContext() {
return fModelContext;
}

View file

@ -8,16 +8,18 @@
* Contributors:
* Wind River Systems - initial API and implementation
*******************************************************************************/
package org.eclipse.dd.dsf.model;
package org.eclipse.dd.dsf.datamodel;
import java.util.ArrayList;
import java.util.List;
import org.eclipse.dd.dsf.concurrent.ThreadSafe;
/**
* Holder for utility static methods for manipulating IDataModelContext
* objects.
* Holder for utility static methods for manipulating IDMContext objects.
*/
public class DMCs {
public class DMContexts {
/**
* Finds a data model context of given type among ancestors of the
@ -28,18 +30,18 @@ public class DMCs {
*/
@ThreadSafe
@SuppressWarnings("unchecked")
public static <V extends IDataModelContext> V getAncestorOfType(IDataModelContext ctx, Class<V> ancestorType) {
public static <V extends IDMContext> V getAncestorOfType(IDMContext ctx, Class<V> ancestorType) {
if (ancestorType.isAssignableFrom(ctx.getClass())) {
return (V)ctx;
}
for (IDataModelContext parent : ctx.getParents()) {
for (IDMContext parent : ctx.getParents()) {
if (ancestorType.isAssignableFrom(parent.getClass())) {
return (V)parent;
}
}
for (IDataModelContext parent : ctx.getParents()) {
for (IDMContext parent : ctx.getParents()) {
V ancestor = getAncestorOfType(parent, ancestorType);
if (ancestor != null) return ancestor;
}
@ -47,23 +49,23 @@ public class DMCs {
}
/**
* Checks all ancestors for a given DMC to see if the given
* Checks all ancestors for a given context to see if the given
* potentialAncestor is in fact an ancestor.
* @param dmc DMC who's ancestors to check.
* @param potentialAncestor Ancestor DMC to look for.
* @param dmc DM Contexts who's ancestors to check.
* @param potentialAncestor Ancestor context to look for.
* @return true if a match is found.
*/
@ThreadSafe
public static boolean isAncestorOf(IDataModelContext dmc, IDataModelContext potentialAncestor) {
public static boolean isAncestorOf(IDMContext dmc, IDMContext potentialAncestor) {
// Check the direct parents for a match.
for (IDataModelContext parentDmc : dmc.getParents()) {
for (IDMContext parentDmc : dmc.getParents()) {
if (potentialAncestor.equals(parentDmc)) {
return true;
}
}
// Recursively check the parents' parents for a match.
for (IDataModelContext parentDmc : dmc.getParents()) {
for (IDMContext parentDmc : dmc.getParents()) {
if (isAncestorOf(parentDmc, potentialAncestor)) {
return true;
}
@ -72,4 +74,23 @@ public class DMCs {
// No match.
return false;
}
/**
* Traverses all the parents of a context and converts the whole
* into a list.
*/
@ThreadSafe
public static List<IDMContext> toList(IDMContext dmc) {
/*
* This method is implemented recursively, which is not necessarily
* the most efficient way to do this.
*/
List<IDMContext> list = new ArrayList<IDMContext>();
list.add(dmc);
for (IDMContext parentDmc : dmc.getParents()) {
list.addAll(toList(parentDmc));
}
return list;
}
}

View file

@ -8,7 +8,7 @@
* Contributors:
* Wind River Systems - initial API and implementation
*******************************************************************************/
package org.eclipse.dd.dsf.model;
package org.eclipse.dd.dsf.datamodel;
import org.eclipse.core.runtime.IAdaptable;
import org.eclipse.dd.dsf.concurrent.Immutable;
@ -22,15 +22,15 @@ import org.eclipse.dd.dsf.concurrent.Immutable;
* retrieve the children and label information for these handles. Because of
* this pattern, services need to be able to return a set of handle objects,
* then as needed clients can retrieve data corresponding to these handles.
* The DMC object is the interface that DSF services should use
* The Data Model Context object is the interface that DSF services should use
* to represent the handle objects that are to be referenced by view model.
* <p>
* <i>Note: DMC objects are meant to be immutable and thus accessible from
* <i>Note: DM contexts are meant to be immutable and thus accessible from
* any thread instead of just the services dispatch thread. This is because
* clients may need to call context objects' methods on non-dispatch thread,
* especially equals and hashCode.</i>
* <p>
* <i>Note #2: DMCs should also avoid holding references to service
* <i>Note #2: DM Contexts should also avoid holding references to service
* instances or other large chunks of data, because some of the clients may
* hold onto these objects for longer time than the life of the service.
* This may prevent the service from being garbage collected, possibly keeping
@ -41,10 +41,10 @@ import org.eclipse.dd.dsf.concurrent.Immutable;
* allows the clients to avoid casting the data class when retrieving data
* for a context object.
*
* @see IDataModelData
* @see IDMData
*/
@Immutable
public interface IDataModelContext<V extends IDataModelData> extends IAdaptable
public interface IDMContext<V extends IDMData> extends IAdaptable
{
/**
* Each model context object needs to track the session from which it
@ -73,5 +73,5 @@ public interface IDataModelContext<V extends IDataModelData> extends IAdaptable
* the client.
* @return parent context of this context.
*/
public IDataModelContext[] getParents();
public IDMContext[] getParents();
}

View file

@ -8,18 +8,20 @@
* Contributors:
* Wind River Systems - initial API and implementation
*******************************************************************************/
package org.eclipse.dd.dsf.model;
package org.eclipse.dd.dsf.datamodel;
import org.eclipse.dd.dsf.concurrent.ConfinedToDsfExecutor;
/**
* Data object containing information regarding a model context. Unlike the
* context object, this object does have to be accessed on the dispatch thread,
* DM Context object, this object does have to be accessed on the dispatch thread,
* unless other-wise noted. And it does not need to be immutable or free of
* references to the service.
* <p>
* This interface is intended primarily to allow for future development of
* a generic API to parametrize data model data.
* references to the service. In fact, to avoid unnecessary duplication of data
* it is most practical for the DM Data object to simply retrieve data directly
* from the service internals (caches, queues, etc).
*/
public interface IDataModelData {
@ConfinedToDsfExecutor("")
public interface IDMData {
/**
* Returns true if the data represented by this object is still valid.

View file

@ -8,14 +8,14 @@
* Contributors:
* Wind River Systems - initial API and implementation
*******************************************************************************/
package org.eclipse.dd.dsf.model;
package org.eclipse.dd.dsf.datamodel;
/**
* Common interface for events that signify changes in the data model.
* The sub-classes should contain specific information about the event, while
* this base class only identifies the DMC that is affected.
* @param <V> DMC that is affected by this event.
* this base class only identifies the DM Context that is affected.
* @param <V> Data Model context type that is affected by this event.
*/
public interface IDataModelEvent <V extends IDataModelContext> {
V getDMC();
public interface IDMEvent <V extends IDMContext> {
V getDMContext();
}

View file

@ -8,7 +8,7 @@
* Contributors:
* Wind River Systems - initial API and implementation
*******************************************************************************/
package org.eclipse.dd.dsf.model;
package org.eclipse.dd.dsf.datamodel;
import org.eclipse.dd.dsf.concurrent.GetDataDone;
import org.eclipse.dd.dsf.service.IDsfService;
@ -16,22 +16,22 @@ import org.eclipse.dd.dsf.service.IDsfService;
/**
* Interface for DSF services that provide model data to clients.
* <p>
* For completeness this service interface derives from <code>IDataModelData</data>
* and has a method which allows clients to retrieve the DMC that represents the
* service data.
* For completeness this service interface derives from <code>IDMData</data>
* and has a method which allows clients to retrieve the DM Context that
* represents the service data.
*/
public interface IDataModelService extends IDsfService, IDataModelData {
public interface IDMService extends IDsfService, IDMData {
/**
* Returns the context representing the service in the data model. It is
* usually used in events to indicate that lists of contexts in this
* service are changed.
*/
IDataModelContext getServiceContext();
IDMContext getServiceContext();
/**
* Retrieves model data object for given context. This method makes it
* un-necessary for every model service to declare a separate method
* for retrieving model data of specific type.
*/
<V extends IDataModelData> void getModelData(IDataModelContext<V> dmc, GetDataDone<V> done);
<V extends IDMData> void getModelData(IDMContext<V> dmc, GetDataDone<V> done);
}

View file

@ -0,0 +1,32 @@
/*******************************************************************************
* 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.datamodel;
import org.eclipse.dd.dsf.service.AbstractDsfService;
/**
* The Data Model Context representing the owner service. The service DM Context
* should be the parent of all contexts originating from the given service.
* <p>
* Note: there should be only one instance of ServiceContext per service, so there
* is no need to implement the equals() methods.
*/
public class ServiceDMContext<V extends IDMService> extends AbstractDMContext<V> {
String fServiceDMID;
public ServiceDMContext(AbstractDsfService service, String serviceDMID) {
super(service, null);
fServiceDMID = serviceDMID;
}
public String toString() { return baseToString() + fServiceDMID; }
}

View file

@ -1,52 +0,0 @@
/*******************************************************************************
* 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;
import org.eclipse.dd.dsf.concurrent.Done;
import org.eclipse.dd.dsf.concurrent.GetDataDone;
import org.eclipse.dd.dsf.model.IDataModelContext;
import org.eclipse.dd.dsf.model.IDataModelData;
import org.eclipse.dd.dsf.model.IDataModelEvent;
import org.eclipse.dd.dsf.model.IDataModelService;
/**
* This is just an initial take at the targets interface.
*/
public interface ITargets extends IDataModelService {
public interface ITargetDMC extends IDataModelContext<ITargetData> {}
public interface ITargetData extends IDataModelData {
String getName();
boolean isConnected();
}
public interface ITargetStateChanged extends IDataModelEvent {}
public interface ICoreDMC extends IDataModelContext<ICoreData> {}
public interface ICoreData extends IDataModelData {
String getName();
boolean isConnected();
IOS.IOSDMC getOSDMC();
}
public interface ICoreStateChanged extends IDataModelEvent {}
public void getTargets(GetDataDone<ITargetDMC> done);
public void getCores(ITargetDMC target, GetDataDone<ICoreDMC> done);
public void connectTarget(ITargetDMC targetDmc, Done done);
public void disconnectTarget(ITargetDMC targetDmc, Done done);
public void connectCore(ITargetDMC targetDmc, Done done);
public void disconnectCore(ITargetDMC targetDmc, Done done);
}

View file

@ -90,6 +90,10 @@ abstract public class AbstractDsfService
*/
@SuppressWarnings("unchecked")
protected void register(String[] classes, Dictionary properties) {
/*
* Ensure that the list of classes contains the base DSF service
* interface, as well as the actual class type of this object.
*/
if (!Arrays.asList(classes).contains(IDsfService.class.getName())) {
String[] newClasses = new String[classes.length + 1];
System.arraycopy(classes, 0, newClasses, 1, classes.length);
@ -102,32 +106,62 @@ abstract public class AbstractDsfService
newClasses[0] = getClass().getName();
classes = newClasses;
}
/*
* Make sure that the session ID is set in the service properties.
* The session ID distinguishes this service instance from instances
* of the same service in other sessions.
*/
properties.put(PROP_SESSION_ID, getSession().getId());
fProperties = properties;
fRegistration = getBundleContext().registerService(classes, this, properties);
/*
* Retrieve the OBJECTCLASS property directly from the service
* registration info. This is the best bet for getting an accurate
* value.
*/
fRegistration.getReference().getProperty(Constants.OBJECTCLASS);
fFilter = generateFilter(fProperties);
fProperties.put(Constants.OBJECTCLASS, fRegistration.getReference().getProperty(Constants.OBJECTCLASS));
/*
* Create the filter for this service based on all the properties. If
* there is a single service instance per session, or if the properties
* parameter uniquely identifies this service instance among other
* instances in this session. Then this filter will fetch this service
* and only this service from OSGi.
*/
fFilter = generateFilter(fProperties);
}
/**
* Generates an LDAP filter to uniquely identify this service.
*/
private String generateFilter(Dictionary properties) {
StringBuffer filter = new StringBuffer();
filter.append("(&");
// Add the service class to the filter.
filter.append('(');
filter.append(Constants.OBJECTCLASS);
filter.append('=');
filter.append(this.getClass().getName());
filter.append(')');
for (Enumeration keys = properties.keys(); keys.hasMoreElements();) {
Object key = keys.nextElement();
filter.append('(');
filter.append(key.toString());
filter.append('=');
filter.append(properties.get(key).toString());
filter.append(')');
Object value = properties.get(key);
if (value instanceof Object[]) {
/*
* For arrays, add a test to check that every element in array
* is present. This is here mainly to handle OBJECTCLASS property.
*/
for (Object arrayValue : (Object[])value) {
filter.append('(');
filter.append(key.toString());
filter.append("=*");
filter.append(arrayValue.toString());
filter.append(')');
}
} else {
filter.append('(');
filter.append(key.toString());
filter.append('=');
filter.append(value.toString());
filter.append(')');
}
}
filter.append(')');
return filter.toString();

View file

@ -220,7 +220,7 @@ public class DsfSession
/**
* Map of registered adapters, for implementing the
* IModelContext.getAdapter() method.
* @see org.eclipse.dd.dsf.model.AbstractDMC#getAdapter
* @see org.eclipse.dd.dsf.datamodel.AbstractDMContext#getAdapter
*/
private Map<Class,Object> fAdapters = Collections.synchronizedMap(new HashMap<Class,Object>());
@ -282,7 +282,7 @@ public class DsfSession
* Registers a IModelContext adapter of given type.
* @param adapterType class type to register the adapter for
* @param adapter adapter instance to register
* @see org.eclipse.dsdp.model.AbstractDMC#getAdapter
* @see org.eclipse.dsdp.model.AbstractDMContext#getAdapter
*/
@ThreadSafe
public void registerModelAdapter(Class adapterType, Object adapter) {
@ -292,7 +292,7 @@ public class DsfSession
/**
* Un-registers a IModelContext adapter of given type.
* @param adapterType adapter type to unregister
* @see org.eclipse.dsdp.model.AbstractDMC#getAdapter
* @see org.eclipse.dsdp.model.AbstractDMContext#getAdapter
*/
@ThreadSafe
public void unregisterModelAdapter(Class adapterType) {
@ -303,7 +303,7 @@ public class DsfSession
* Retrieves an adapter for given type for IModelContext.
* @param adapterType adapter type to look fors
* @return adapter object for given type, null if none is registered with the session
* @see org.eclipse.dsdp.model.AbstractDMC#getAdapter
* @see org.eclipse.dsdp.model.AbstractDMContext#getAdapter
*/
@ThreadSafe
public Object getModelAdapter(Class adapterType) {